<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ teamwork - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ teamwork - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 16:31:49 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/teamwork/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build Successful Low-Code Apps: The Power of Knowledge Transfer in Development Teams ]]>
                </title>
                <description>
                    <![CDATA[ Low-code models, such as Microsoft's Power Platform, make it simple for anyone to start creating applications. The barriers to entry are relatively low, as users need only a work or school email to ge ]]>
                </description>
                <link>https://www.freecodecamp.org/news/low-code-knowledge-transfer/</link>
                <guid isPermaLink="false">66d87a73191c724ea0c7ef03</guid>
                
                    <category>
                        <![CDATA[ Low Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Collaboration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Wed, 04 Sep 2024 15:19:15 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724883531478/4fa7979a-e61a-4268-94dc-a48dfcf17b4b.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Low-code models, such as Microsoft's Power Platform, make it simple for anyone to start creating applications. The barriers to entry are relatively low, as users need only a work or school email to get started. Developers can also quickly release new applications into the wild.</p>
<p>But as this happens, questions arise, such as who supports these applications? And who will make the updates if there is a feature request or bug?</p>
<p>Many low-code applications are often created by a single developer, inherently leading to a single point of failure.</p>
<p>And don't let the advertised simplicity of low-code trick you into thinking anyone can edit the app, fix any issues, and add new features. Low code can still contain complexity, and complex solutions can quickly become a problem for organizations and teams that leverage dozens, if not hundreds, of other low- or non-low-code dependencies.</p>
<p>This doesn't mean that organizations should strictly restrict who can create these applications. Doing so would contradict the very purpose of low code. It's a model that empowers stakeholders themselves to rapidly prototype ideas and develop low-cost solutions to problems that, in traditional development, might cost millions of dollars.</p>
<p>In this low-code world, both organizations and developers need a plan. Developers, specifically, should have a plan to transfer knowledge of their products, whether working in a team or independently.</p>
<h2 id="heading-how-to-simplify-complexity">How to Simplify Complexity</h2>
<p>Our relatively small team has created numerous low-code solutions, primarily leveraging Microsoft's suite of products. Some of these solutions are simple low-code canvas apps, while others contain hundreds of dependencies that are anything but low-code.</p>
<p>We've learned, sometimes the hard way, the importance of ensuring maintainability in our development. This means supporting the applications we build and enabling existing and new team members to support them in the future.</p>
<p>Initially, we found ourselves drawn to the premise of being able to create products that solve problems quickly. Before we knew it, we had our own problem: how do we support the array of these products, ensuring that not just us but new team members could do so as well?</p>
<h3 id="heading-slow-down-to-speed-up">Slow Down to Speed Up</h3>
<p>This might sound contrary to the low-code paradigm, but taking frequent pauses to consider the long-term impacts of your decisions is critical to ensuring the tools you build today can be supported tomorrow.</p>
<p>This does not mean reverting back to the speeds of traditional software development, but you should not consider building low-code products as a race to the finish line.</p>
<h3 id="heading-pair-programming">Pair Programming</h3>
<p>Incorporating traditional software development practices can significantly benefit the low-code movement. Even if your applications involve little to no conventional code, concepts like pair programming can be effectively applied when building low-code products.</p>
<p>Take, for example, the process of building a Power App. Traditionally, only one person could edit an app at a time. Although that limitation has changed—multiple people can now edit an app simultaneously—defining a collaborative process remains crucial.</p>
<p>Our team often employs a primary "driver" approach, where one member leads the development while another observes, providing real-time feedback and suggestions.</p>
<p>This method keeps everyone engaged and helps mitigate the effects of tunnel vision on the product. And this collaborative approach is especially valuable for more complex aspects of the application.</p>
<p>For more straightforward tasks, we often work in parallel but stay closely connected via Teams or Zoom, ready to coordinate and ensure each different component is part of a cohesive whole.</p>
<h3 id="heading-applicationcode-reviews">Application/Code Reviews</h3>
<p>Low code doesn't mean no code. It is challenging to create robust applications with drag-and-drop alone. Even something like Power Apps has its own language called Power FX.</p>
<p>Schedule time each week to walk through or review others' applications to become familiar with their creations. Look for places where things can be improved, and be ready to accept feedback on your creations, too.</p>
<p>If you're using traditional code in your project, some of this can be accomplished with PRs. For purely low-code implementations, keep a document of changes and have a sign-off process to ensure other team members can access new changes.</p>
<p>For example, imagine adding a new screen to a Canvas app, allowing users to update personal settings. That change should be documented as unreviewed until at least one other team member has reviewed and signed off on this new feature.</p>
<h3 id="heading-get-other-team-members-involved">Get Other Team Members Involved</h3>
<p>If you're on a team, each product should involve at least two people to avoid single points of failure. Ensure each product has a primary and secondary developer or product owner. For larger teams, allow that secondary role to rotate, ensuring each member is more intimately involved with the team's products.</p>
<p>One way to get others involved and up to speed is to have other team members add new features or fix bugs in existing products under the guidance of the primary or lead developer. This knowledge transfer will help cultivate ownership in the various products your team supports, leading to higher engagement and motivation.</p>
<p>Additionally, as the workload is distributed more evenly across the team, bottlenecks are reduced, allowing for more expeditious handling of fixing bugs and enhancing products.</p>
<h2 id="heading-when-a-hands-on-approach-isnt-possible">When a Hands-On-Approach isn't Possible...</h2>
<p>Much of what I describe above is an attempt to get others involved with projects. The more we touch these things, the better we will understand them.</p>
<p>Inevitably, however, when this hands-on experience isn't possible, it is essential to have practices that can mitigate the effects of isolated development—that is, a development done by one or just a few people.</p>
<p>The two most important things we can do are create and maintain comprehensive documentation about our products and use standard practices as much as possible. We'll talk about documentation first.</p>
<h3 id="heading-document-document-document">Document, Document, Document</h3>
<p>As you've probably experienced, the low-code movement allows applications to be created quickly. The more applications exist, the fewer touchpoints we have with older ones. While those touchpoints are critical to the knowledge transfer process, relying on them alone isn't enough.</p>
<p>Whether you're on a team or a solo developer, creating documentation that describes each aspect of your products is critical. For small projects, this may be a simple text document. For larger projects, you could utilize a SharePoint site. Of course, as products become even more complex, the various dependencies will likely have their own documentation (for example, Git repositories).</p>
<p>Here is an example of how you might document a product you are building:</p>
<p>Let's say you have an application that allows users to reserve a conference room for meetings. That application consists of a user interface (such as a Canvas app) and custom code that creates a follow-up reminder for the person who reserved the meeting a day before. This reminder could send an email to remind the user about the meeting, and if the meeting is no longer occurring, encourage them to cancel the reservation. Finally, this product could also have a reporting element, where administrators can see conference room utilization over time to better understand demand.</p>
<p>Here is how you might document this project:</p>
<ol>
<li><p>Establish a single source of truth about this project, such as a SharePoint page.</p>
</li>
<li><p>This page briefly describes the project, the product owners, and the lead developers.</p>
</li>
<li><p>The page would also briefly describe this project's components (Canvas app, custom code, and reporting dashboard).</p>
</li>
<li><p>Finally, you would include documentation on any easy-to-overlook aspects or non-standard project implementations (more on standardization later).</p>
</li>
</ol>
<p>The SharePoint page handles the high-level overview of the project and gets you pointed in the right direction. Regarding the individual components, the Canvas app will include comments and notes in the version history, and your custom code will leverage Git and often include a detailed readme.</p>
<p>Documentation can be challenging, but it is critical. While documentation should be comprehensive, it should complement the hands-on knowledge transfer techniques described above.</p>
<h3 id="heading-standardize-as-much-as-possible">Standardize as Much as Possible</h3>
<p>Whether it is low-code or traditional development, it is important to have standard practices. This is even more important when talking about low code because of the speed at which things can be developed and potentially get out of control.</p>
<p>From project planning, design, development, and testing to cross training team members, make time to create standard practices for each phase.</p>
<p>Standardization shouldn't be considered a way to eliminate the need for cross-training and documentation but rather a way to complement those stages and reduce the time needed in those areas.</p>
<p>If you can approach a problem the same way every time, you can spend time discussing those non-standard and easy-to-forget parts of what you're building.</p>
<p>Here are some questions to get you started:</p>
<ol>
<li><p>What big-picture steps will each application require? Who will be involved in those steps?</p>
</li>
<li><p>What tools will you use? (for example, Power Apps, Appian, Pega)</p>
</li>
<li><p>Can you support traditional development? If so, how will that look?</p>
</li>
<li><p>What is your philosophical approach to development? For example, should you design the user interface or business logic first? What database will you use? (for example, SharePoint or Dataverse)</p>
</li>
<li><p>What conventions will you use in your code? (for example, naming conventions for screens and variables)</p>
</li>
<li><p>What does this knowledge transfer or cross-training process look like? Do you have dedicated times each week to review each other's work?</p>
</li>
</ol>
<p>Of course, this list goes on. The more you learn, the more you'll realize what needs to be discussed. Get started by creating a Standard Operating Procedure (SOP), and be prepared to edit it early and often.</p>
<h2 id="heading-what-if-i-am-a-solo-developer">What if I am a Solo Developer?</h2>
<p>If you're a solo developer, it may be easy to think that the recommendations above don't apply. But this couldn't be further from the truth. Creating and maintaining a knowledge-transfer framework is even more critical as a solo developer. While co-developing and pair programming are not directly applicable, the concepts still apply.</p>
<p>For example, take time to meet other developers and ask for feedback. At a minimum, it will be an excellent way to meet other people doing the same thing. And, of course, with AI taking a front row in programming, you can always leverage AI to help you learn new techniques and optimize the things you are building.</p>
<p>Finally, documentation and standard practices are just as necessary for the individual developer. First, if you ever work with others, you'll have a reference for your work. Second, these things will act as an external reminder of how you intend to solve development-related problems in the future.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>While low-code platforms offer incredible speed and flexibility, they can also introduce challenges when it comes to maintenance. Rapid development, if not managed carefully, can lead to issues that undermine the long-term success of your applications.</p>
<p>But by intentionally slowing down and establishing a clear plan for knowledge transfer, you can safeguard the future of your critical products. This approach ensures that applications remain supported and sustainable, both now and for years to come.</p>
<p>Stay curious.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Collaborative Coding? Pair Programming, Mob Programming, and How it All Works ]]>
                </title>
                <description>
                    <![CDATA[ By Andrej Kovacevic Coding can be challenging, but it can become a lot easier if you have the right strategies and tools.  After all, as noted software engineer and writer Joel Spolsky says, "it is harder to read code than to write it." One way to ma... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/collaborative-coding-tips/</link>
                <guid isPermaLink="false">66d45d9bc7632f8bfbf1e3d7</guid>
                
                    <category>
                        <![CDATA[ Collaboration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pair programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 02 May 2022 20:13:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/collaborative-coding-tips.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Andrej Kovacevic</p>
<p>Coding can be challenging, but it can become a lot easier if you have the right strategies and tools. </p>
<p>After all, as noted software engineer and writer <a target="_blank" href="http://blogs.perl.org/users/buddy_burden/2013/12/perl-and-me-part-4-a-worthy-program-exceedingly-well-read.html#note1">Joel Spolsky</a> says, "it is harder to read code than to write it."</p>
<p>One way to make your development projects more successful is with collaborative coding. This refers to the process of working on the code with a team or with another developer. In a project that uses collaborative coding, each team member helps build the code and checks it for bugs or errors.</p>
<p>Working in pairs or teams helps finished code contain <a target="_blank" href="https://www.freecodecamp.org/news/how-to-be-a-team-player-in-the-tech-world-c78aa9f4e898/">fewer mistakes</a> and bugs, and this results in better code quality and projects being completed more quickly.</p>
<p>It also enables faster debugging and greater project resiliency, as this setup makes it easier for other developers to take over in case one of the developers has to leave the project.</p>
<p>But collaborative coding won't produce all of these benefits by default. Making them happen comes down to how you implement your collaborative development strategy and how you execute it. Here are four points to consider when doing so.</p>
<h2 id="heading-you-need-a-secure-development-process">You Need a Secure Development Process</h2>
<p>Although having multiple sets of eyes checking a project's code should produce a net benefit for the code's security — it can also introduce a new type of vulnerability into the mix. This is because sharing code through a collaboration platform creates the possibility of a data breach.</p>
<p>Humans, after all, are the weakest link in the cybersecurity chain. So, the larger the team, the greater the odds that someone will make an unforced security error during development. </p>
<p>And things like exposed or stolen login credentials can endanger a project — especially one that is designed to handle sensitive information like banking and personal details.</p>
<p>This means that project managers must choose a collaboration platform that's built with security in mind. Some collaborative coding platforms already have built-in security features, but others do not. And different types of coding projects will call for different feature sets, so there's no one-size-fits-all solution.</p>
<p>There are plenty of collaborative coding platforms that may fit the bill, however. <a target="_blank" href="https://teletype.atom.io/">Teletype</a>, for example, comes with end-to-end encryption and the option to use self-destructing messages. </p>
<p>Another popular option is <a target="_blank" href="https://brackets.io/">Brackets</a>, which comes with data protection when interacting with third-party plugins and has a mechanism for preventing unapproved access and privilege escalation.</p>
<p>Some teams or developers might use established collaboration platforms not specifically designed for coding. Microsoft Teams, for instance, can facilitate casual coding collaboration. And although it's not an inherently insecure system, it has weaknesses that developers can address with an additional <a target="_blank" href="https://www.avanan.com/teams-security">Microsoft Teams Security</a> solution.</p>
<p>These solutions include features like malware protection, URL protection, access control over confidential data, compliance tools, and security alerts – which all improve platform security significantly. </p>
<p>Regardless of the platform you choose, though, it is important to use security tools or to install third-party security solutions that ensure the best possible security for your project.</p>
<h2 id="heading-choose-the-right-platform-for-the-job">Choose the Right Platform for the Job</h2>
<p>It's also important to recognize that security isn't the only consideration when you're choosing a collaborative coding platform. </p>
<p>It's also critical to choose one that will provide every team member with the tools and resources necessary to do their job. The right platform should meet the following criteria:</p>
<h3 id="heading-its-made-for-a-specific-programming-language-or-ecosystem">It's made for a specific programming language or ecosystem</h3>
<p>There are many benefits in using a platform that is created for a specific programming language. First, it most likely has all of the tools necessary to efficiently work on a project in a particular language. And it won't have unnecessary features added to cater to other requirements and preferences.</p>
<p>A language-specific platform is also designed with best practices in mind for developers working with particular languages or frameworks. So, for example, when working with dynamic programming languages such as Go, Ruby, and Python, it is preferable to use a platform like <a target="_blank" href="https://aws.amazon.com/cloud9/">Cloud9</a>.</p>
<h3 id="heading-its-fast-to-setup">It's fast to setup</h3>
<p>Ideally, everyone involved should already be familiar with the collaborative coding platform that you'll use. But if this isn't the case, it's important to choose one that is easy to learn with minimal to no configuration involved. </p>
<p>A platform that requires IDE, server, terminal, codebase, and library configuration along with other setup procedures is not the most suitable option for live coding between pairs or teams of developers.</p>
<h3 id="heading-it-should-have-a-customizable-user-interface">It should have a customizable user interface</h3>
<p>Programming is a heavily detail-driven job and developers tend to have their own preferences when it comes to the user interface so they can work easily and conveniently. </p>
<p>Forcing everyone to use a platform they are not comfortable with is not a good way to proceed with collaborative coding. So it helps to have the option to modify the UI or dashboard to some extent.</p>
<p>The bottom line is that the collaborative coding platform should be easy to use for everyone. Developers may be highly skilled people, but not everyone is a master of everything. Those who are collaborating should agree on a platform and working arrangement that works for everyone.</p>
<h2 id="heading-define-clear-team-roles-at-the-outset">Define Clear Team Roles at the Outset</h2>
<p>We can categorize collaborative coding into three general setups: </p>
<ul>
<li>pair programming</li>
<li>mob programming, and </li>
<li>code sharing. </li>
</ul>
<p>And understanding the inner workings of each of these setups is important, as different coding projects require different setups. </p>
<p>But it's equally important to understand the roles of the team members in each setup and to define them before beginning to code.</p>
<p>As the phrase suggests, <a target="_blank" href="https://www.freecodecamp.org/news/things-ive-learned-from-pair-programming-interviews-35a4db7d7443/">pair programming</a> involves two participants. Usually, one serves as the driver and the other acts as the navigator. The driver writes the code while the navigator reviews the output. </p>
<p>In this setup, the driver is responsible for the tactical aspects of the job while the navigator sets the strategic direction of the code. The two may then switch their roles to have a more thorough look at what they have produced.</p>
<p><a target="_blank" href="https://searchsoftwarequality.techtarget.com/definition/mob-programming">Mob programming</a> is similar to pair programming but involves more than two people. To avoid making it a chaotic or disorganized arrangement, it is also important to have the driver-navigator role assignments. </p>
<p>It is slightly more complicated, though, because there are more than two developers who have to agree on how to assign the driver-navigator roles. This means that clear communication and mutual respect are crucial.</p>
<p>The code-sharing setup does not require a driver-navigator dynamic. Instead, the collaborating developers only share their respective code to allow each other to review, modify, debug, or add to each other's code. </p>
<p>This is the type of collaboration that open source developers tend to rely on because it allows newcomers to participate at will and existing developers to pause their work whenever they need to.</p>
<p>The participants here may work on the code together in real-time or asynchronously. What's important is that they have a reliable system for version control. </p>
<p>That's where version control systems like <a target="_blank" href="https://git-scm.com/">Git</a> excel. They help teams to avoid doing duplicate work and make sure that all developers are reviewing, revising, or adding to the latest version of the code at all times.</p>
<h2 id="heading-create-skill-balanced-teams-for-best-results">Create Skill Balanced Teams for Best Results</h2>
<p>While some would consider collaborative coding as an <a target="_blank" href="https://www.smashingmagazine.com/2020/04/collaborative-coding-ultimate-career-hack/">opportunity to learn</a> from more experienced and proficient coders, that doesn't mean every collaborative project is conducive to that. </p>
<p>This is because for certain types of projects, having too much of a disparity in the skill level of team members can grind the whole project to a halt.</p>
<p>This is a problem that feeds one of the biggest criticisms of collaborative coding as a development method. When team members must contribute as equals but lack the skills to keep up, progress stalls. When time is of the essence, creating a skill-balanced team is the only option.</p>
<p>That said, collaborative coding can be an opportunity for collaborative learning, but only when deadlines aren't involved. In that scenario, team members can take their time to learn from the work of their more experienced peers. And in the end, everyone benefits from the experience.</p>
<p>But if the goal is to make the project a collaborative learning endeavor, it is important to make that clear from the get-go. Otherwise, the more experienced developers could feel like they've been duped into providing training instead of getting the project done. And that never ends well.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The advantages of collaborative coding are undeniable — but there are drawbacks to consider too. </p>
<p>So, before deciding to go into the collaborative route, it is important to carefully scrutinize the pros and cons as they relate to a specific project. </p>
<p>And for developers who wish to try their hand at collaborative coding, it's a good idea to get familiar with the popular tools and platforms used for such projects beforehand. That way, both the project planners and team members will get the most out of the collaborative process — but without encountering some of the issues that it can entail.</p>
<p><em>Featured photo by snowing 12 - stock.adobe.com</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Git and GitHub in a Team like a Pro – Featuring Harry and Hermione 🧙 ]]>
                </title>
                <description>
                    <![CDATA[ By Damian Demasi In this tutorial, you will learn how to work in a team with a central repository on GitHub. You will work on issues, commits, pull requests, code reviews, and more. I don't consider myself an expert on Git, but I have learned a lot a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-git-and-github-in-a-team-like-a-pro/</link>
                <guid isPermaLink="false">66d45e017df3a1f32ee7f7f5</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 07 Jan 2022 18:13:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/Frame-17---freeCodeCamp.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Damian Demasi</p>
<p>In this tutorial, you will learn how to work in a team with a central repository on GitHub. You will work on issues, commits, pull requests, code reviews, and more.</p>
<p>I don't consider myself an expert on Git, but I have learned a lot about it in my first month working as a software developer. </p>
<p>I wrote this tutorial to share how Git is used in professional environments. Bear in mind that there is not just a single way of using Git – so this is just one approach, and it may differ from what you see in your professional career.</p>
<p>A good read to start working with Git workflows is this <a target="_blank" href="https://www.atlassian.com/git/tutorials/comparing-workflows">Comparing Workflows</a> tutorial.</p>
<h2 id="heading-the-project"><strong>The Project</strong></h2>
<p>Harry and Hermione had the great idea of building a SaaS app to allow people to build their own potions online and share them with the rest of the world. They named it <strong>Potionfy</strong>, and this will be their first start-up.</p>
<p><img src="https://media.giphy.com/media/BttC0fsMuGXVS/giphy.gif" alt="Image" width="500" height="209" loading="lazy"></p>
<p>They decided to use GitHub as the central repository in which all their work was going to be stored. They chose React and Ruby on Rails as the app technology stack.</p>
<h2 id="heading-the-team"><strong>The Team</strong></h2>
<p>Potionfy will be bootstrapped by Harry and Hermione themselves by using their savings. They will work their home garage and they expect to have an MVP ready in 4 weeks.</p>
<p>Let's see how they will work together in building the SaaS product and the obstacles they will have to overcome in doing so.</p>
<h2 id="heading-initial-project-setup"><strong>Initial Project Setup</strong></h2>
<p>This project will use two fictional team members – Harry and Hermione – with two separate GitHub accounts. So you may want to start creating two accounts on GitHub for this.</p>
<p>Bonus: in order to simplify things, if you have a Gmail account you can use your Gmail address with a plus and a string after the first part of it, and all email communications will be centralised in one account, like so:</p>
<pre><code>my_email_address+harry@gmail.com
my_email_address+hermione@gmail.com
</code></pre><p>More on this <a target="_blank" href="https://support.google.com/a/users/answer/9308648?hl=en">here</a>.</p>
<h3 id="heading-step-1-how-to-create-two-different-github-accounts">Step 1: How to create two different GitHub accounts</h3>
<p>In order to follow along with this tutorial, you'll need two different GitHub accounts. I chose to create two, but you can just use your own and create another one. Here is how my set-up looks:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8n5im9orxfgn5cf19ch.png" alt="Harry and Hermione GitHub accounts" width="1710" height="873" loading="lazy"></p>
<h3 id="heading-step-2-how-to-set-up-your-local-development-environment">Step 2: How to set up your local development environment</h3>
<p>We are going to use a local development environment and set up Git on it. I decided to use a virtual machine running Linux, but you can use your own environment (I just want to avoid any kind of configuration problem with Git).</p>
<p>We have to make sure Git is installed in our system:</p>
<pre><code>git --version
</code></pre><p>This command should return the version of Git that is installed in your system. In my case, my virtual Ubuntu didn't have it installed, so I ran:</p>
<pre><code>sudo apt install git
</code></pre><h3 id="heading-step-3-teamwork-considerations">Step 3: teamwork considerations</h3>
<p>Harry will be the one working locally in our development environment, and Hermione will choose to work directly on GitHub by using an online VSCode (more on this later).</p>
<h2 id="heading-how-to-get-started-working-on-the-project"><strong>How to Get Started Working on the Project</strong></h2>
<h3 id="heading-step-1-how-to-create-the-repository-and-build-the-team-for-free">Step 1: How to create the repository and build the team (for free)</h3>
<p>Hermione is the leader of the team, as she is more experienced in coding, so she has decided to create a new repository to host the code for the SaaS product. </p>
<p>To create the repository, she simply used the GitHub web interface and clicked on the <code>Repositories</code> tab, and then on the <code>New</code> button. She named the repository <code>potionfy</code> and she added a short description and a <code>Readme.md</code> file.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92a2v6z1asks9og4pows.png" alt="Potionfy repository" width="855" height="927" loading="lazy"></p>
<p>After the repository was created, she invited Harry to work on it. To do so, she clicked on the <code>Settings</code> tab in the <code>potionfy</code> repository, then in the <code>Manage access</code> option, and finally in the <code>Add people</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3veijbtrpirpxpx5qivl.png" alt="Add people to the repository" width="852" height="872" loading="lazy"></p>
<p>By entering Harry's GitHub username (or email address) in the pop-up window and clicking on the <code>Add Harry(...) to this repository</code>, she managed to send the invitation to Harry.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6o5mdaunh0wnbwil28c4.png" alt="Inviting Harry" width="493" height="345" loading="lazy"></p>
<p>A couple of seconds later, Harry received the invitation to his email:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82utres034fp4hmpvkta.png" alt="Invitation email" width="603" height="726" loading="lazy"></p>
<p>He accepted it, and by doing so, both team members were ready to start working on their project.</p>
<p><strong>NOTE:</strong> In case the invitation link does not work (as in my case), Harry needs to go to Hermione's GitHub profile, click on the <code>potionfy</code> repository, and accept the invitation there:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71u7wj0v3cicwnpinbhw.png" alt="Accepting invitation (part 1)" width="939" height="643" loading="lazy"></p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4d69vm27g19jo6kcvbv.png" alt="Accepting invitation (part 2)" width="939" height="643" loading="lazy"></p>
<h3 id="heading-step-2-how-to-create-a-file">Step 2: How to create a file</h3>
<p>Hermione started the project by creating the initial file the Potionfy SaaS product will use: <code>index.html</code>. </p>
<p>In order to do so, she created the file using the GitHub web interface by positioning herself in the repository and clicking on the <code>Add file</code> &gt; <code>Create new file</code> buttons.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gdlz27zm8k8cpziv7be.png" alt="Image description" width="852" height="602" loading="lazy"></p>
<p>Then she added the name of the file, its content, and a meaningful commit message. After clicking on the <code>Commit new file</code> button, the file was created on the repository.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/si7jxizohz7adle8rtr0.png" alt="Creating a file" width="852" height="1296" loading="lazy"></p>
<h3 id="heading-step-3-how-to-create-an-issue-and-work-on-it">Step 3: How to create an issue and work on it</h3>
<p>Hermione needs to move on to work on the marketing related to Potionfy launch, so she told Harry to add a simple landing message to the <code>index.html</code> file. So, she proceeded to create an <strong>issue</strong> in the repository by clicking on the <code>Issues</code> tab and clicking on the <code>New issue</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rasnvg01wtaxt35p4oa8.png" alt="New issue" width="852" height="620" loading="lazy"></p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mgf8tpr35i1dbzpnno2l.png" alt="New issue description" width="852" height="727" loading="lazy"></p>
<p>After the issue was created, Harry took a look at it (also by going to the <code>issues</code> tab in the Potionfy repository) and let Hermione know that he will be working on it by leaving a comment and assigning the issue to himself.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6n6z1xfed0iy71y3nkpa.png" alt="Issue assignment" width="852" height="1063" loading="lazy"></p>
<p>By working with this dynamic, the team will know who is working on what.</p>
<h3 id="heading-step-4-how-to-set-up-the-local-development-environment">Step 4: How to set up the local development environment</h3>
<p>In order to work on the project's <code>index.html</code> file, Harry chose to work locally, so he needed to clone the <code>potionfy</code> repository in his development environment (the Linux virtual machine).</p>
<p>The first thing he had to do was set up the SSH keys to work with GitHub. He followed GitHub's <a target="_blank" href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent">Generating a new SSH key and adding it to the ssh-agent</a> tutorial to do so. He then added the key to his GitHub account, following the <a target="_blank" href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account">Adding a new SSH key to your GitHub account</a> tutorial.</p>
<p>Then, Harry opened Hermione's repository on GitHub and copied the link to clone it:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vj9me394xsugdav4wouh.png" alt="Cloning repository" width="852" height="631" loading="lazy"></p>
<p>Now in his local development environment, he created a new directory in which all his work would be centralised:</p>
<pre><code>$ mkdir ~/development
$ cd ~/development
</code></pre><p>Finally, he cloned the repository by typing <code>git clone</code> and pasting the code he just copied from GitHub (which is the <em>address</em> of the repository):</p>
<pre><code>$ git clone git@github.com:Hermione-Colo-Codes/potionfy.git
</code></pre><p>In this way, he now has a local copy of the repository and he is ready to start working on it.</p>
<pre><code>$ ll
total <span class="hljs-number">12</span>
drwxrwxr-x  <span class="hljs-number">3</span> parallels parallels <span class="hljs-number">4096</span> Nov <span class="hljs-number">17</span> <span class="hljs-number">07</span>:<span class="hljs-number">34</span> ./
drwxr-xr-x <span class="hljs-number">23</span> parallels parallels <span class="hljs-number">4096</span> Nov <span class="hljs-number">17</span> <span class="hljs-number">07</span>:<span class="hljs-number">33</span> ../
drwxrwxr-x  <span class="hljs-number">3</span> parallels parallels <span class="hljs-number">4096</span> Nov <span class="hljs-number">17</span> <span class="hljs-number">07</span>:<span class="hljs-number">34</span> potionfy/
</code></pre><h3 id="heading-github-workflow">GitHub workflow</h3>
<p>In order to work on a repository, this is the workflow GitHub recommends:</p>
<ol>
<li>Create a branch</li>
<li>Make changes</li>
<li>Create a pull request</li>
<li>Address review comments</li>
<li>Merge your pull request</li>
<li>Delete your branch</li>
</ol>
<p>For more information about this, you can read <a target="_blank" href="https://docs.github.com/en/get-started/quickstart/github-flow">this document</a>.</p>
<h4 id="heading-step-1-create-a-branch">Step 1: Create a branch</h4>
<p>As it is a good practice not to work on the master branch directly, Harry created a new branch related to the issue on which he will be working. </p>
<p>He chose to do this on the GitHub repository, but he could have done the same in his local environment using Git commands.</p>
<p>He chose a meaningful name and prefixed the name with the number of the related issue (which is <code>1</code>, in this case).</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6yne1wb24kctulcw654.png" alt="Creating a branch" width="852" height="602" loading="lazy"></p>
<p>More information about how to create a branch on GitHub can be <a target="_blank" href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository">found here</a>.</p>
<h4 id="heading-step-2-work-on-the-branch-locally">Step 2: Work on the branch locally</h4>
<p>After the branch was created, Harry started working on it.</p>
<h5 id="heading-git-pull"><code>git pull</code></h5>
<p>The first thing he did was a <code>pull</code> of the whole repository so he could see the branch in his local development environment.</p>
<pre><code class="lang-bash">~/development/potionfy$ git pull
Warning: Permanently added the ECDSA host key <span class="hljs-keyword">for</span> IP address <span class="hljs-string">'13.237.44.5'</span> to the list of known hosts.
From github.com:Hermione-Colo-Codes/potionfy
 * [new branch]      1-add-landing-message -&gt; origin/1-add-landing-message
Already up to date.
</code></pre>
<h5 id="heading-git-checkout"><code>git checkout</code></h5>
<p>With the new branch in his environment, he switched to it by using the <code>git checkout &lt;name_of_branch&gt;</code> command. After doing so, he ensured he was working in the correct branch with the <code>git branch</code> command.</p>
<pre><code class="lang-bash">~/development/potionfy$ git checkout 1-add-landing-message 
Branch <span class="hljs-string">'1-add-landing-message'</span> <span class="hljs-built_in">set</span> up to track remote branch <span class="hljs-string">'1-add-landing-message'</span> from <span class="hljs-string">'origin'</span>.
Switched to a new branch <span class="hljs-string">'1-add-landing-message'</span>

~/development/potionfy$ git branch
* 1-add-landing-message
  main
</code></pre>
<h5 id="heading-solve-the-issue">Solve the issue</h5>
<p>Harry started working on solving the issue. In order to do so, he opened the <code>index.html</code> file and added a <code>h1</code> header to it.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rhinjvy8z4ouozekolm.png" alt="Making changes to the file" width="1137" height="632" loading="lazy"></p>
<p>After the changes were made, he saw how Git reacted to this change.</p>
<pre><code class="lang-bash">~/development/potionfy$ git status
On branch 1-add-landing-message
Your branch is up to date with <span class="hljs-string">'origin/1-add-landing-message'</span>.

Changes not staged <span class="hljs-keyword">for</span> commit:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to update what will be committed)
  (use <span class="hljs-string">"git restore &lt;file&gt;..."</span> to discard changes <span class="hljs-keyword">in</span> working directory)
    modified:   index.html

no changes added to commit (use <span class="hljs-string">"git add"</span> and/or <span class="hljs-string">"git commit -a"</span>)
parallels@parallels-Parallels-Virtual-Platform:~/development/potionfy$
</code></pre>
<p>He then added the file to the staging area with the <code>git add</code> command and committed the change with the <code>git commit</code> command.</p>
<pre><code class="lang-bash">~/development/potionfy$ git add -A

~/development/potionfy$ git commit -m <span class="hljs-string">"Add landing message. #1"</span>

~/development/potionfy$ git status
</code></pre>
<p>Note how the commit message also includes the id of the issue, which in this case is <code>#1</code>.</p>
<h5 id="heading-push-to-the-repository">Push to the repository</h5>
<p>The next step Harry needs to do is to push the changes to the repository.</p>
<pre><code class="lang-bash">~/development/potionfy$ git push
</code></pre>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spgnh14xpr1wnqlis2k3.png" alt="Pushing changes" width="1279" height="1074" loading="lazy"></p>
<h5 id="heading-create-a-pull-request">Create a pull request</h5>
<p>Harry then clicked on the <code>Compare and pull request</code> button in the GitHub repository (making sure his branch was selected in the branch left drop-down menu).</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nsmrf4fbqloojq41tk0.png" alt="Pull request" width="1268" height="1314" loading="lazy"></p>
<p>This pull request will be analysed by Hermione and she will decide if it can be merged to the master branch or not.</p>
<h3 id="heading-quick-recap-so-far">Quick recap so far</h3>
<p>Up to this point in the tutorial, we learned how Harry and Hermione decided to build a SaaS app to allow people to build their own potions online and share them with the rest of the world. They named it <strong>Potionfy</strong>.</p>
<p>Hermione created a remote repository, then an <code>issue</code> to address the task of building a landing page, and how Harry worked on that <code>issue</code> locally and created a <code>pull request</code> once he finished working on it.</p>
<p>Now, we are going to see:</p>
<ul>
<li>how Hermione reviews Harry's code,</li>
<li>how the code is merged on the master branch,</li>
<li>the decision of using a <code>develop</code> branch,</li>
<li>how the team works in the develop branch and merges changes into main,</li>
<li>and how the team solves merge conflicts.</li>
</ul>
<p><img src="https://media.giphy.com/media/VwUquCGtIatGg/giphy.gif" alt="Image" width="500" height="202" loading="lazy"></p>
<h2 id="heading-how-to-do-code-reviews"><strong>How to Do Code Reviews</strong></h2>
<h3 id="heading-step-1-how-to-create-a-code-review">Step 1: How to create a code review</h3>
<p>Hermione has finished with her marketing and promotion tasks, and she now has time to review Harry's code. </p>
<p>In order to do so, she opens the GitHub repository and clicks on the <code>Pull requests</code> tab to find Harry's pull request.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qytmh2qm30u2tfxfdc1p.png" alt="First pull request" width="852" height="649" loading="lazy"></p>
<p>After clicking on it, she then clicks on the <code>Commits</code> tab, and finally in Harry's last commit (this is just one way of accessing the files modified on the pull request).</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zr6b36csbr9btula3rh9.png" alt="Reviewing code" width="852" height="777" loading="lazy"></p>
<p>She is not entirely convinced about the <code>&lt;h1&gt;</code> code, so she clicks on the plus icon that appears when she hovers that line of code, and writes a comment to Harry. Finally, she clicks on the <code>Start a review</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ws8b6hfmuo9kqmun15q.png" alt="Comment on the code" width="852" height="1063" loading="lazy"></p>
<p>As she has no other comments about the code, she now clicks on the <code>Review changes</code> button to make the review visible to the rest of the team.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hybyz2iwa71gsqbztvum.png" alt="Making a review" width="852" height="936" loading="lazy"></p>
<p>You can find more information about making reviews in this <a target="_blank" href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-proposed-changes-in-a-pull-request">Reviewing proposed changes in a pull request</a> article.</p>
<h3 id="heading-step-2-how-to-address-the-review-and-create-a-code-change">Step 2: How to address the review and create a code change</h3>
<p>Harry checks his pull request and finds a new conversation there: Hermione's review.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pklnu1xdc1wmvf2mkl0f.png" alt="Working on the review" width="836" height="1128" loading="lazy"></p>
<p>Harry answers Hermione's comment and clicks on the <code>Resolve conversation</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofalfmz3ukitvnng7yha.png" alt="Solving conversation" width="836" height="907" loading="lazy"></p>
<p>Now that the conversation is resolved, Hermione can submit the review indicating that <strong>there are requested changes</strong> so Harry can actually work on them.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/reok6k1teor9ho43vltv.png" alt="Submitting review" width="849" height="1070" loading="lazy"></p>
<p><strong>Note:</strong> this is just one version of the review process in GitHub, and it can differ from the actual way your team chooses to handle them.</p>
<p>Harry checks the pull request again and finds that it has <code>Changes requested</code>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6rz496wfrvxdesf0ij75.png" alt="Changes requested" width="836" height="1172" loading="lazy"></p>
<h3 id="heading-step-3-how-to-implement-the-changes">Step 3: How to implement the changes</h3>
<p>As Harry likes to work locally, he continues working on the branch he had created in order to implement the code changes.</p>
<pre><code class="lang-bash">$ git checkout 1-add-landing-message
</code></pre>
<p>Once he is sure he is working on the correct branch, he makes the changes in the <code>index.html</code> file.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/no7pmw3pck2cpgi3nl5n.png" alt="Implementing changes" width="950" height="663" loading="lazy"></p>
<p><strong>Note:</strong> for simplicity sake, we are not creating a separate CSS file here.</p>
<p>Once Harry finishes tweaking the code, he stages the changes, commits them (making sure to include the <code>id</code> of the issue because he is still working on it), and pushes them to GitHub.</p>
<pre><code class="lang-bash">$ git add -A

$ git commit -m <span class="hljs-string">"Add colour and remove text. #1"</span>

$ git push
</code></pre>
<h3 id="heading-step-4-how-to-merge-the-pull-request">Step 4: How to merge the pull request</h3>
<p>Now it's Hermione's turn. She goes to the pull request and finds a new commit: the one Harry did and pushed to GitHub.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4n6yso4pn6rfkdj0xioj.png" alt="New commit" width="835" height="1168" loading="lazy"></p>
<p>She then clicks on the <code>Files changed</code> tab and finds the ones that she suggested implemented on the <code>index.html</code> file.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmudklpfre4op0afjem3.png" alt="Changes in the file" width="850" height="648" loading="lazy"></p>
<p>As she is satisfied with the changes, she proceeds to approve them by clicking on the <code>Review changes</code> button and selecting the <code>Approve</code> option.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7soa00zfq791oa50b9j.png" alt="Approving changes" width="850" height="863" loading="lazy"></p>
<p>Harry sees that his pull request was approved by Hermione, and he proceeds to merge it into the main branch of the project.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hdjyzbh1vxpyhf9joy0.png" alt="Merging pull request" width="839" height="1335" loading="lazy"></p>
<p>He decided not to delete the branch, as he wants to leave it there for future reference (although it would be a good idea to delete it).</p>
<p>As Hermione is satisfied with how the issue was solved, she proceeds to close it by going to the <code>Issues</code> tab and clicking on the <code>Close issue</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/reqhbp9nrmvzxj46d9ms.png" alt="Closing issue" width="838" height="1245" loading="lazy"></p>
<p>If you want to see a graphical representation of the whole process up to this point, you can click on the <code>Insights</code> tab and then on the <code>Network</code> option. You will be able to actually see how the branching and merging were performed.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u87v2ie8y93dq8ielyuq.png" alt="Graphical representation" width="1347" height="712" loading="lazy"></p>
<h2 id="heading-how-to-use-a-develop-branch-in-git"><strong>How to Use a <code>develop</code> Branch in Git</strong></h2>
<p>When working with real projects, merging changes into the main branch like you saw up to this point is not recommended. </p>
<p>Instead of working directly with the <code>main</code> branch (often called <code>production</code>), you will be working with a <code>develop</code> branch. You will be branching issues out of that <code>develop</code> branch and merging them back into the <code>develop</code> branch. </p>
<p>Once a group of issues have been solved, that <code>develop</code> branch will be merged into the <code>main</code> (or <code>production</code>) branch, usually denoting a version change in the app.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/94wbcj99uvf39ax8f3ab.png" alt="Develop branch" width="2844" height="1204" loading="lazy"></p>
<p>Hermione is aware of this, and now that the landing page is live and accessible to customers, she decided to preserve that <em>production environment</em> and work on a development branch. </p>
<p>In order to do so, she creates a <code>develop</code> branch out of the <code>main</code> one, so she and Harry can work on that branch without impacting the production environment.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7okjo7adstn9af3rymu.png" alt="Creating a develop branch" width="853" height="602" loading="lazy"></p>
<h2 id="heading-how-to-handle-merge-conflicts-in-git"><strong>How to Handle Merge Conflicts in Git</strong></h2>
<p>Hermione wants to add a new feature to the landing page: a form to capture clients' emails. In order to do so, she creates a new issue.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4v5lyxbk8a18fjvet99o.png" alt="New issue" width="853" height="724" loading="lazy"></p>
<p>Once the issue is created, Harry decides to start working on it. To do so, <strong>he branches out from the <code>develop</code> branch</strong> (by selecting that branch on the GitHub interface) a new one called <code>3-email-form</code> (including the issue number at the front to make it clear how this branch will relate to the issues).</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/km1xvg06alcri2d3q2uk.png" alt="New issue branch from develop" width="851" height="723" loading="lazy"></p>
<p>He then pulls that branch locally and starts working on it.</p>
<pre><code class="lang-bash">$ git pull

$ git checkout 3-form
</code></pre>
<p>Harry decides to include a simple form into the <code>index.html</code> file:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"mailto:hermione@potionfy.com"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">enctype</span>=<span class="hljs-string">"text/plain"</span>&gt;</span>
Name:<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
    E-mail:<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"mail"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Send"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"reset"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Reset"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p><strong>Note:</strong> This code is just to exemplify how Harry is working on a file and it's not how this type of form could actually be built.</p>
<p>Harry stages and commits his changes locally using the <code>Contact form. #3</code> message.</p>
<pre><code class="lang-bash">$ git add -A

$ git commit -m <span class="hljs-string">"Contact form. #3"</span>

$ git push
</code></pre>
<p><img src="https://media.giphy.com/media/7Yif3ae99ksCc/giphy.gif" alt="Image" width="500" height="206" loading="lazy"></p>
<p>Before Harry could create a new pull request, Hermione decides to build a placeholder for the form on the <code>index.html</code> file on her own. In order to do so, <strong>she creates a new branch</strong> out of <code>develop</code> called <code>3-email-form-placeholder</code>.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vtqld9mij5mxoj56qx4r.png" alt="Hermione's branch" width="851" height="723" loading="lazy"></p>
<p>To work on the <code>index.html</code> file, she uses the GitHub online code editor (basically, a VSCode for the web). In order to open it, she just presses the <code>.</code> key on her keyboard and the GitHub page is transformed into a VSCode interface (like magic 😉).</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/agznz5qsohwq8w7xh4xx.png" alt="VSCode online" width="851" height="386" loading="lazy"></p>
<p>She then proceeds to add the following code to the file:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"mailto:harry@potionfy.com"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">enctype</span>=<span class="hljs-string">"text/plain"</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>After saving the file, she commits the changes right there on her browser window by using VSCode's graphical interface:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26bow6vevor0j2bz3g1e.png" alt="Committing changes" width="853" height="404" loading="lazy"></p>
<p>Once the commit is complete, she opens GitHub again and decides to create her own pull request and merge her changes to the <code>develop</code> branch.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ucvh19hp86eh6vwth49.png" alt="Creating a pull request" width="851" height="893" loading="lazy"></p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5p2ldzkvch67ziutdw5.png" alt="Merging changes to develop" width="851" height="887" loading="lazy"></p>
<p><img src="https://media.giphy.com/media/OUwzqE4ZOk5Bm/source.gif" alt="Image" width="250" height="121" loading="lazy"></p>
<p>On the other hand, Harry also decides to create a <code>pull request</code> to merge his changes into the <code>develop</code> branch.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slmwjb3s1z263tnbhvye.png" alt="Harry's pull request" width="851" height="776" loading="lazy"></p>
<p>At this point, GitHub lets him know that his pull request won't be able to merge automatically to the <code>develop</code> branch.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xvyambidieetr4u3puhi.png" alt="Image description" width="851" height="869" loading="lazy"></p>
<p>Harry supposes that his branch is no longer reflecting the state of the <code>develop</code> branch and that the <code>develop</code> branch has changed because someone else merged changes affecting the <code>index.html</code> file on which he was working on. Nevertheless, he proceeds to create a pull request.</p>
<p>What he sees next is GitHub's way of letting him know that there is a conflict affecting the file he modified. He proceeds to click on the <code>Resolve conflicts</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gtxo3qpizp3gfcfpeo14.png" alt="A conflict" width="837" height="893" loading="lazy"></p>
<p>He can now see that the <code>index.html</code> indeed was modified, and the changes made to that file are affecting the lines he himself modified.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdg7jgxt3zcrwbn6p66h.png" alt="Conflicting changes" width="837" height="839" loading="lazy"></p>
<p>For more information about solving conflicts, you can read the <a target="_blank" href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github">Resolving a merge conflict on GitHub</a> article.</p>
<p>Harry proceeds to modify the file directly on the GitHub site to remove the conflicting changes and then clicks on the <code>Mark as resolved</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ijk9wdc6aenfwbzrt8z.png" alt="Solving conflict" width="837" height="748" loading="lazy"></p>
<p>Once the conflict is marked as resolved, he clicks on the <code>Commit merge</code> button.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cp87juwh255hou1kipgv.png" alt="Commit merge" width="837" height="424" loading="lazy"></p>
<p>Finally, his branch was conflict-free and he can merge his pull request (assuming Hermione reviewed his code and approved it, just as she did earlier).</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7m3lr63hu68nv0xdk15i.png" alt="Merging pull request" width="837" height="974" loading="lazy"></p>
<p>Conflicts ofter arise when teammates are working on different branches that affect a common file. A great way to prevent merge conflicts is to do a <code>pull</code> request on the <code>develop</code> branch, merge that updated <code>develop</code> branch into the branch you are working on, and then do a <code>push</code> followed by a <code>pull request</code>.</p>
<pre><code class="lang-bash">$ git branch
x-my-branch <span class="hljs-comment"># This is an example name</span>

$ git checkout develop

$ git pull

$ git checkout x-my-branch

$ git merge develop

<span class="hljs-comment"># You make some changes on the files of the x-my-branch branch</span>

$ git add -A

$ git commit -m <span class="hljs-string">"&lt;a message&gt;"</span>

$ git push
</code></pre>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>After working on their landing page, Harry and Hermione managed to get lots of email addresses from potential customers and continued developing their MVP. They managed to get funding from a local venture capital firm, and they are now in the process of hiring other developers to launch Potionfy to the public. </p>
<p>I'm sure they would love to take a look at your resume to consider you for a position in their company, so good luck!</p>
<p><img src="https://media.giphy.com/media/gbErpwcLlizvi/giphy.gif" alt="Image" width="245" height="126" loading="lazy"></p>
<p>🗞 If you enjoyed this article, you may like other articles I publish. The best way to know about them would be by <a target="_blank" href="https://mailchi.mp/22b236f812b1/subscribe-to-newsletter"><strong>subscribing to my newsletter</strong></a>.</p>
<p>🐦 You can follow and contact me on my <a target="_blank" href="https://twitter.com/DamianDemasi"><strong>Twitter</strong></a> account.</p>
<p>Cheers!</p>
<p>Damian.-</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Better Git Commit Messages – A Step-By-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ When first introduced to Git, it's typical for developers to feel uncomfortable with the process.  You might feel uncertainty when encountering the Git commit message, unsure how to properly summarize the changes you've made and why you've made them.... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/</link>
                <guid isPermaLink="false">66bc4cb17fa38392bfab812e</guid>
                
                    <category>
                        <![CDATA[ Collaboration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Natalie Pina ]]>
                </dc:creator>
                <pubDate>Tue, 04 Jan 2022 22:34:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/gitcommitmessage.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When first introduced to Git, it's typical for developers to feel uncomfortable with the process. </p>
<p>You might feel uncertainty when encountering the Git commit message, unsure how to properly summarize the changes you've made and why you've made them. But the earlier in your career you can develop good committing habits, the better.</p>
<p>Have you ever wondered how you can improve your Git commit messages? This guide outlines steps to elevate your commit messages that you can start implementing today.</p>
<p>This article assumes you already understand basic Git workflow. If not, I suggest reading through the <a target="_blank" href="https://guides.github.com/introduction/git-handbook/">Git Handbook</a>.</p>
<p>It is also important to note that you should follow your team's conventions first and foremost. These tips are based on suggestions based upon research and general consensus from the community. But by the end of this article you may have some implementations to suggest that may help your team's workflow.</p>
<blockquote>
<p>I think git enters a whole other realm the moment you start working in teams -- there are so many cool different flows and ways that people can commit code, share code, and add code to your repo open-source or closed-source-wise. — <a target="_blank" href="https://syntax.fm/">Scott Tolinski, Syntax.fm</a>.</p>
</blockquote>
<h2 id="heading-why-should-you-write-better-commit-messages">Why should you write better commit messages?</h2>
<p>I challenge you to open up a personal project or any repository for that matter and run <code>git log</code> to view a list of old commit messages. The vast majority of us who have run through tutorials or made quick fixes will say "Yep... I have absolutely no idea what I meant by 'Fix style' 6 months ago." </p>
<p>Perhaps you have encountered code in a professional environment where you had no idea what it was doing or meant for. You've been left in the dark without code comments or a traceable history, and even wondering "what are the odds this will break everything if I remove this line?"</p>
<h3 id="heading-back-to-the-future">Back to the Future</h3>
<p>By writing good commits, you are simply future-proofing yourself. You could save yourself and/or coworkers hours of digging around while troubleshooting by providing that helpful description. </p>
<p>The extra time it takes to write a thoughtful commit message as a letter to your potential future self is extremely worthwhile. On large scale projects, documentation is imperative for maintenance. </p>
<p>Collaboration and communication are of utmost importance within engineering teams. The Git commit message is a prime example of this. I highly suggest setting up a convention for commit messages on your team if you do not already have one in place.</p>
<h2 id="heading-the-anatomy-of-a-commit-message">The Anatomy of a Commit Message</h2>
<h4 id="heading-basic">Basic:</h4>
<p><code>git commit -m &lt;message&gt;</code></p>
<h4 id="heading-detailed">Detailed:</h4>
<p><code>git commit -m &lt;title&gt; -m &lt;description&gt;</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-03-at-10.31.49-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-5-steps-to-write-better-commit-messages">5 Steps to Write Better Commit Messages</h2>
<p> Let's summarize the suggested guidelines:</p>
<ol>
<li>Capitalization and Punctuation: Capitalize the first word and do not end in punctuation. If using Conventional Commits, remember to use all lowercase. </li>
<li>Mood: Use imperative mood in the subject line. Example – <code>Add fix for dark mode toggle state</code>. Imperative mood gives the tone you are giving an order or request.</li>
<li>Type of Commit: Specify the type of commit. It is recommended and can be even more beneficial to have a consistent set of words to describe your changes. Example: Bugfix, Update, Refactor, Bump, and so on. See the section on Conventional Commits below for additional information. </li>
<li>Length: The first line should ideally be no longer than 50 characters, and the body should be restricted to 72 characters.</li>
<li>Content: Be direct, try to eliminate filler words and phrases in these sentences (examples: though, maybe, I think, kind of). Think like a journalist. </li>
</ol>
<h3 id="heading-how-to-find-your-inner-journalist">How to Find Your Inner Journalist</h3>
<p>I never quite thought my Journalism minor would benefit my future career as a Software Engineer, but here we are!   </p>
<p>Journalists and writers ask themselves questions to ensure their article is detailed, straightforward, and answers all of the reader's questions. </p>
<p>When writing an article they look to answer <em>who</em>, <em>what</em>, <em>where</em>, <em>when</em>, <em>why</em> and <em>how.</em>  For committing purposes, it is most important to answer the what and why for our commit messages. </p>
<p>To come up with thoughtful commits, consider the following: </p>
<ul>
<li>Why have I made these changes?</li>
<li>What effect have my changes made?</li>
<li>Why was the change needed?</li>
<li>What are the changes in reference to?</li>
</ul>
<p>Assume the reader does not understand what the commit is addressing. They may not have access to the story addressing the detailed background of the change.</p>
<p>Don't expect the code to be self-explanatory. This is similar to the point above. </p>
<p>It might seem obvious to you, the programmer, if you're updating something like CSS styles since it is visual. You may have intimate knowledge on why these changes were needed at the time, but it's unlikely you will recall why you did that hundreds of pull requests later. </p>
<p>Make it clear <em>why</em> that change was made, and note if it may be crucial for the functionality or not.  </p>
<p>See the differences below:</p>
<ol>
<li><code>git commit -m 'Add margin'</code></li>
<li><code>git commit -m 'Add margin to nav items to prevent them from overlapping the logo'</code></li>
</ol>
<p>It is clear which of these would be more useful to future readers.   </p>
<p>Pretend you're writing an important newsworthy article. Give the headline that will sum up what happened and what is important. Then, provide further details in the body in an organized fashion.   </p>
<p>In filmmaking, it is often quoted "show, don't tell" using visuals as the communication medium compared to a verbal explanation of what is happening.</p>
<p>In our case, "<strong>tell</strong>, don't [just] show" – though we have some visuals at our disposal such as the browser, most of the specifics come from reading the physical code.  </p>
<p>If you're a VSCode user, download the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=waderyan.gitblame">Git Blame</a> extension. This is a prime example of when useful commit messages are helpful to future developers. </p>
<p>This plugin will list the person who made the change, the date of the changes, as well as the commit message commented inline. </p>
<p>Imagine how useful this could be in troubleshooting a bug or back-tracing changes made. Other honorable mentions to see Git historical information are <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory">Git History</a> and <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens">GitLens</a>. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-03-at-10.45.49-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conventional-commits">Conventional Commits</h2>
<p>Now that we've covered basic commit structure of a good commit message, I'd like to introduce Conventional Commits to help provide some detail on creating solid commit messages.   </p>
<p>At D2iQ, we use Conventional Commit which is a great practice among engineering teams. Conventional Commit is a formatting convention that provides a set of rules to formulate a consistent commit message structure like so:</p>
<pre><code>&lt;type&gt;[optional scope]: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">description</span>&gt;</span>

[optional body]

[optional footer(s)]</span>
</code></pre><p>The commit type can include the following:</p>
<ul>
<li><code>feat</code> – a new feature is introduced with the changes</li>
<li><code>fix</code> – a bug fix has occurred</li>
<li><code>chore</code> – changes that do not relate to a fix or feature and don't modify src or test files (for example updating dependencies)</li>
<li><code>refactor</code> – refactored code that neither fixes a bug nor adds a feature </li>
<li><code>docs</code> – updates to documentation such as a the README or other markdown files</li>
<li><code>style</code> – changes that do not affect the meaning of the code, likely related to code formatting such as white-space, missing semi-colons, and so on.</li>
<li><code>test</code> – including new or correcting previous tests </li>
<li><code>perf</code> – performance improvements</li>
<li><code>ci</code> – continuous integration related</li>
<li><code>build</code> – changes that affect the build system or external dependencies </li>
<li><code>revert</code> – reverts a previous commit </li>
</ul>
<p>The commit type subject line should be all lowercase with a character limit to encourage succinct descriptions. </p>
<p>The optional commit body should be used to provide further detail that cannot fit within the character limitations of the subject line description. </p>
<p>It is also a good location to utilize <code>BREAKING CHANGE: &lt;description&gt;</code> to note the reason for a breaking change within the commit. </p>
<p>The footer is also optional. We use the footer to link the JIRA story that would be closed with these changes for example: <code>Closes D2IQ-&lt;JIRA #&gt;</code> .</p>
<h4 id="heading-full-conventional-commit-example">Full Conventional Commit Example</h4>
<pre><code>fix: fix foo to enable bar

This fixes the broken behavior <span class="hljs-keyword">of</span> the component by doing xyz. 

BREAKING CHANGE
Before <span class="hljs-built_in">this</span> fix foo wasn<span class="hljs-string">'t enabled at all, behavior changes from &lt;old&gt; to &lt;new&gt;

Closes D2IQ-12345</span>
</code></pre><p>To ensure that these committing conventions remain consistent across developers, commit message linting can be configured before changes are able to be pushed up. <a target="_blank" href="https://commitizen-tools.github.io/commitizen/">Commitizen</a> is a great tool to enforce standards, sync up semantic versioning, along with other helpful features.</p>
<p>To aid in adoption of these conventions, it's helpful to include guidelines for commits in a contributing or README markdown file within your projects.</p>
<p>Conventional Commit works particularly well with semantic versioning (learn more at <a target="_blank" href="https://semver.org/">SemVer.org</a>) where commit types can update the appropriate version to release.  You can also <a target="_blank" href="https://www.conventionalcommits.org/en/v1.0.0/">read more about Conventional Commits here</a>.</p>
<h2 id="heading-commit-message-comparisons">Commit Message Comparisons</h2>
<p>Review the following messages and see how many of the suggested guidelines they check off in each category.</p>
<h4 id="heading-good">Good</h4>
<ul>
<li><code>feat: improve performance with lazy load implementation for images</code></li>
<li><code>chore: update npm dependency to latest version</code></li>
<li><code>Fix bug preventing users from submitting the subscribe form</code></li>
<li><code>Update incorrect client phone number within footer body per client request</code></li>
</ul>
<h4 id="heading-bad">Bad</h4>
<ul>
<li><code>fixed bug on landing page</code></li>
<li><code>Changed style</code></li>
<li><code>oops</code></li>
<li><code>I think I fixed it this time?</code></li>
<li>empty commit messages</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Writing good commit messages is an extremely beneficial skill to develop, and it helps you communicate and collaborate with your team. Commits serve as an archive of changes. They can become an ancient manuscript to help us decipher the past, and make reasoned decisions in the future.</p>
<p>There is an existing set of agreed-upon standards we can follow, but as long as your team agrees upon a convention that is descriptive with future readers in mind, there will undoubtedly be long-term benefits.</p>
<p>In this article, we've learned some tactics to level up our commit messages. How do you think these techniques can improve your commits?</p>
<p>I hope you've learned something new, thanks for reading! </p>
<p>Connect with me on Twitter <a target="_blank" href="https://twitter.com/ui_natalie">@ui_natalie</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Documentation For Your Next Software Development Project ]]>
                </title>
                <description>
                    <![CDATA[ By Kevin Hanson Do you have a new software project on the horizon? You should prepare for success. The process of development determines the outcome. And a crucial part of making sure things run smoothly is having the right documentation in place.  B... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-documentation-for-your-next-software-development-project/</link>
                <guid isPermaLink="false">66d45f638812486a37369cd5</guid>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 07 Apr 2021 16:40:47 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/04/sharon-mccutcheon-tn57JI3CewI-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Kevin Hanson</p>
<p>Do you have a new software project on the horizon? You should prepare for success. The process of development determines the outcome. And a crucial part of making sure things run smoothly is having the right documentation in place. </p>
<p>Before you start designing, coding, building, and testing, take the time to prepare all the software documentation you need. It’s not the most exciting part of a software project, but it does make all the difference.</p>
<h2 id="heading-how-important-is-documentation">How important is documentation?</h2>
<p>The software industry is one that is particularly fast-paced. To keep up, you might want to start developing as soon as you get a great idea. But hold your horses. Cutting corners won’t actually bring you further. </p>
<p>Time spent on documentation rather than developing is not lost. On the contrary, if it’s done right, it will not only save you time, but also improve your product. As a project scales, the documentation will serve as guidelines that will enable you to do things right on the first try. No guesswork or free-styling.</p>
<p>A project manager who has a great overview of the project in their head is great—but developers or new team members can't access that. Details can get lost in communication. </p>
<p>Technical documentation can make or break a project. If every step of the way for a project is well-documented, it can run smoothly and save time. No one-on-one conversations to give the right people the right information, and with that, no misunderstandings. </p>
<h2 id="heading-why-write-project-documentation">Why write project documentation?</h2>
<h3 id="heading-your-project-will-depend-less-on-individual-people">Your project will depend less on individual people</h3>
<p>With detailed documentation, onboarding new team members becomes a breeze. When your product is growing, changing, and scaling, you can easily refer new talent to the necessary documentation and have them up and running in no time. </p>
<p>This also works the other way around: if a team member leaves, they don’t take all their knowledge about the project with them. It’s still there in the documentation.</p>
<p>A project with great documentation simply relies less on the individuals working on it. It has its own framework that anyone should be able to work with. It makes your software project more resilient against unexpected challenges.</p>
<p><img src="https://lh4.googleusercontent.com/3HOT45VEHgCy2W7I2nHWn9lenDmNRlGSZl4nhup8-G9xdSJ0xpYXxy4Uv9nVd9E8zAr9NLP_2ZTQOXmldtdfNpuRkVaO4RMIXfL4N0Rs9bQ-3bWkc6SQSggQcwMvEhZa8FzvAss" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-communication-with-stakeholders-and-clients-becomes-easier">Communication with stakeholders and clients becomes easier</h3>
<p>But the benefits of having a well-documented software project go beyond internal processes. </p>
<p>With the right documentation, it also becomes easier to present your product to stakeholders, making it more understandable what you’ll be creating. Anything that’s on paper is easier to review and understand than ideas in your head. </p>
<p>Documentation for your product helps in the pitching process, but also when you're further down the line. If a client has approved the documents you presented, it’s easy to fall back on them whenever an issue arises. No he-said-she-said: it’s all right there, ready to be referred to. </p>
<p>At the end of the day, a successful project isn’t only about the product you build—it’s also the relationships you built. Prevent any issues while you can and ensure a pleasant collaboration.</p>
<h2 id="heading-how-to-write-good-documentation">How to write good documentation</h2>
<p>All of this doesn’t require encyclopedia-like documentation. Just make sure you cover the essentials for your project specifically. In this article, we’ll give you some advice on how to do that. </p>
<h2 id="heading-make-an-inventory-of-what-documents-you-will-need">Make an inventory of what documents you will need</h2>
<p>Do you have your whole project already planned out in your head? That’s a great start—but I’d still recommend that you document it. If you don’t see the sense of creating any documentation whatsoever for yourself, remember that you’re mainly doing it for the users of your end project. </p>
<p>They will notice: not only in how well the software tool works, but also in how fast it was delivered—without you having to make a lot of changes after launch. </p>
<p>But what kind of documents will you actually need? Depending on the size of the project, you could need documentation that will guide daily processes. Or maybe you mostly need a framework for the bigger picture. </p>
<p>Let’s divide software documentation into two categories: <strong>process</strong> and <strong>product</strong> documentation.</p>
<h3 id="heading-what-is-product-documentation">What is product documentation?</h3>
<p>Product documentation describes the end goal: the actual product you are building. How it works, how to work with it, technological specifications, manuals–anything you need to know once the product exists.</p>
<p>For your developers, the most important product documentation is the system documentation. It explains how the software product works, why it works in a certain way, and how to work with it. </p>
<p>For the actual users of your software product, user documentation is essential. Think tutorials, FAQs for troubleshooting, and a manual that will help them use and love your product the way you intended.</p>
<h3 id="heading-what-is-process-documentation">What is process documentation?</h3>
<p>See this as the roadmap that will bring your project from idea to existence. In this you can include:</p>
<ul>
<li>Test standards and schedules: making sure everyone tests your product in the same way, so the results will actually be relevant.</li>
<li>Meeting notes: save them, so you can hand them over to your client whenever a disagreement arises.</li>
<li>Project plans: how will you be building your product? What milestones do you want to reach along the way and when? </li>
</ul>
<h2 id="heading-determine-crucial-information">Determine crucial information</h2>
<p>Within your process documentation, you can decide how detailed you’ll map out the steps and process. If you’re an experienced software developer or project manager, you will know what questions are likely to come up, and which discussions will arise. </p>
<p>If you’re new to this, you might be clueless as to what you can or should include. Here are some examples you might overlook or not think of that can fast-track your project development.</p>
<h3 id="heading-data-and-privacy-compliance">Data and privacy compliance</h3>
<p>If it’s relevant to your product, create guidelines that will help your team stay in between the lines of what’s allowed regarding data regulations. What rules are in place? What process should employees follow so they know they’re safe?</p>
<h3 id="heading-emergency-plans">Emergency plans</h3>
<p>What do you do when your server goes offline? What’s the first step after a security breach? What if your hardware tomorrow decides it doesn't want to work anymore? Having answers to questions like these can save you a lot of time and money.</p>
<h3 id="heading-visual-documentation">Visual documentation</h3>
<p>Don’t worry designers, technical documentation is not just words. People are still mostly visual thinkers. That’s why diagrams can help you make workflows clearer. </p>
<p>But visuals that explain how the product should be working at the end of the project also contributes to a more streamlined way of working—especially if what you’re building is quite complex.</p>
<p>Still unsure what to include? Ask the people it will concern. Sit your team around the table and determine together what they want to have on paper to prevent issues down the line.</p>
<p><img src="https://lh6.googleusercontent.com/gju29y8Fb3L9q-D51hBU8KlcYQLk95MZJdVOlu8d5rv8pqFaxaFUxT2xBCZfKFUolhCSjq_T3vCNvCli1H-HFy6Y0dFXuea-DXM_gYTr5pqkYHVAMFpFPpxuWRY8nHqQZV3jFoY" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-write-effective-technical-documents">Write effective technical documents</h2>
<p>Don’t worry, I’ll actually tell you how. Most people aren’t born writers–let alone born technical writers. Writing technical documents can seem like a boring and at the same time daunting task. After all, making a mistake in a technical document could have pretty big implications for the product or process. Making an error in a user manual could, too.</p>
<h3 id="heading-watch-your-language">Watch your language</h3>
<p>You don't need to impress anyone with a technical document. Your team members will know that you are knowledgeable, without you using jargon where it's simply not necessary.</p>
<p>Many people feel the need to write way more difficult language when it comes to business-related documents. But you’re still dealing with people, humans you speak to in a certain way. Try to use that way of speaking in your writing as well to make your documents more comprehensible. </p>
<p>Keep your sentences short. Simplify your words. Prevent misunderstandings.</p>
<p>The goal of technical documentation is to make things clearer and speed things up. Not to produce more questions. This applies even more so on documents that are meant for the end-user. </p>
<p>For bonus points, write different documentation based on different user personas. Take <a target="_blank" href="https://www.python.org/doc/">Python</a> for instance, which has great documentation for a variety of different users from beginners to seasoned professionals. </p>
<h3 id="heading-organize-your-thoughts">Organize your thoughts</h3>
<p>Yes, if you are planning to write a plan, you’ll need to have a plan for writing it. Having a clear structure in your technical documentation is what will save the readers and users time. Use headers. Find a chronological order. </p>
<p>If it’s your first rodeo, simply start with using a template for your technical document. You don’t have to reinvent the wheel.</p>
<p><img src="https://lh6.googleusercontent.com/SGovnSuDHuk6EZ2mvXbntPgjrlvEYmeJqffjTaNp17RyN63d9pLXGJuvXi5zhFbaIU_xxupMHvDJLLG_hbVkU9T7Apxwj7TuffzL7tC5wdPAobNOXYm2Y4g-hYT4W1XQTDUARKA" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-time-to-test">Time to test</h3>
<p>Let someone else read your technical documentation to make sure it’s easy to understand and covers all relevant aspects. </p>
<p>Too often, user manuals are just seen as a side-product and not included in the testing. Set yourself up for success by including it in your tests and development.</p>
<h2 id="heading-do-yourself-a-favor-for-future-projects">Do yourself a favor for future projects</h2>
<p>Creating technical documentation doesn’t just benefit the project you’re working on now. It can also help future projects, as the framework is already there. Just make the necessary changes based on your product and past experience and you’re ready to start developing.  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Git and Git Workflows – a Practical Guide ]]>
                </title>
                <description>
                    <![CDATA[ By John Mosesman Everyone says you should learn Git—and you should—but let's be honest: Git is kind of hard. Even almost ten years into my software development career, I am still learning about the underlying Git fundamentals and how to use Git more ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/practical-git-and-git-workflows/</link>
                <guid isPermaLink="false">66d45f6f706b9fb1c166b993</guid>
                
                    <category>
                        <![CDATA[ Collaboration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 01 Apr 2021 16:08:23 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/60635fd39618b008528a9920.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By John Mosesman</p>
<p>Everyone says you should learn Git—and you should—but let's be honest: Git is kind of hard.</p>
<p>Even almost ten years into my software development career, I am still learning about the underlying Git fundamentals and how to use Git more effectively. </p>
<p>It wasn't too long ago that I realized <a target="_blank" href="https://twitter.com/johnmosesman/status/1306255666718310401">I had a fundamental misunderstanding</a> of a key command I'd used countless times.</p>
<p>Like many other areas in programming, I believe the best way to learn is to just start <em>doing.</em> </p>
<p>Just start being productive with the tool—the fundamentals and edge cases will get sorted out over time. </p>
<p>So in this tutorial that's exactly what we'll do. We'll work through a series of examples to build a from-the-ground-up understanding of how to use Git and ultimately collaborate with your teammates.</p>
<p>In doing so, we'll use simple commands and explain the underlying concepts as they're useful—but only to the extent that they aid understanding. </p>
<p>There's definitely a lot more to Git than is presented here, but these are things you'll learn as you work with it over time.</p>
<p>I also will not be using any tree diagrams (like the one below) because they only confuse me, and I've never had to think about Git in this way to be productive as a software developer.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/hero.svg" alt="Image" width="600" height="400" loading="lazy">
<em>https://www.atlassian.com/git/tutorials/using-branches/git-checkout</em></p>
<p>Here's what we'll cover. Don't let this list intimidate you, we'll go step by step.</p>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-install-git-and-set-up-a-github-account">Installing git and setting up a GitHub account</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-new-repository-in-github">How to create a new repository in GitHub</a></li>
<li><a class="post-section-overview" href="#heading-how-to-clone-a-git-repository">Cloning the repository</a></li>
<li><a class="post-section-overview" href="#heading-git-branches">Git branches</a></li>
<li><a class="post-section-overview" href="#heading-how-to-check-the-status-of-a-git-project">How the check the status of a Git project</a> </li>
<li><a class="post-section-overview" href="#heading-how-to-make-our-first-commit">How to make our first commit</a></li>
<li><a class="post-section-overview" href="#heading-how-to-push-up-our-first-commit-to-github">How to push up our first commit to GitHub</a></li>
<li><a class="post-section-overview" href="#heading-how-to-add-another-commit-in-git">How to add another commit in Git</a></li>
<li><a class="post-section-overview" href="#heading-how-to-stage-changes-in-git">How to stage changes in Git</a></li>
<li><a class="post-section-overview" href="#heading-how-to-view-the-git-diff">How to view the Git diff</a></li>
<li><a class="post-section-overview" href="#heading-how-to-collaborate-with-others-in-git">How to collaborate with others in Git</a></li>
<li><a class="post-section-overview" href="#heading-feature-branches-in-git">Feature branches in Git</a></li>
<li><a class="post-section-overview" href="#heading-git-workflows-for-collaboration">Git workflows for collaboration</a></li>
<li><a class="post-section-overview" href="#heading-how-to-merge-a-branch-in-git">How to merge a branch in Git</a></li>
<li><a class="post-section-overview" href="#heading-pull-request-workflow">Pull request workflow</a></li>
<li><a class="post-section-overview" href="#heading-how-to-bring-our-local-up-to-date">How to bring our local up to date</a></li>
<li><a class="post-section-overview" href="#heading-how-to-retrieve-remote-data">How to retrieve remote data</a></li>
<li><a class="post-section-overview" href="#heading-how-to-fix-merge-conflicts-in-git">How to fix merge conflicts in Git</a></li>
<li><a class="post-section-overview" href="#heading-review-how-to-start-a-new-feature-workflow">Review: how to start a new feature workflow</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<p>So with all of that said, I encourage you to follow along with the examples on your own machine—let's start!</p>
<h2 id="heading-how-to-install-git-and-set-up-a-github-account">How to install Git and set up a GitHub account</h2>
<p>First, some boring stuff we need to do to get up and running.</p>
<p>If you already have Git installed, have made a GitHub account (or use any other provider like GitLab or Bitbucket), and you have setup an SSH key, you can skip this section.</p>
<p>If not, you'll first need to <a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git">install Git</a>.</p>
<p>Secondly, we'll be using GitHub in this tutorial, so signup for a <a target="_blank" href="https://github.com/join">GitHub account here.</a></p>
<p>After you have a GitHub account, you'll need to create an SSH key to push your code from your local machine to GitHub (this key proves to GitHub when you push code that you are "you").</p>
<p>It's not difficult—just <a target="_blank" href="https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent">follow the steps here.</a></p>
<h2 id="heading-how-to-create-a-new-repository-in-github">How to create a new repository in GitHub</h2>
<p>The next thing we'll do is create a new repository in Github. </p>
<p>It's simple. Just click the "New" repository button on your home page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/Screen-Shot-2021-03-31-at-7.30.33-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new repository</em></p>
<p>Next, choose a name for the repository and whether you want the repo to be public or private. You can optionally add a README file if you'd like, and then click "Create repository."</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/Screen-Shot-2021-03-31-at-7.29.07-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Configuring the new repo</em></p>
<p>I've called my repository <a target="_blank" href="https://github.com/johnmosesman/practical-git-tutorial">practical-git-tutorial</a>. This repo has all of the finished steps of this tutorial already in it, so if you want to you can always use it as a reference.</p>
<h2 id="heading-how-to-clone-a-git-repository">How to clone a Git repository</h2>
<p>To start, we'll "clone" the repo. Cloning a repo means downloading all of the project's code and metadata from the source—which in this case is GitHub.</p>
<p>To clone a repo, we use <code>git clone &lt;URL&gt;</code>. </p>
<p>I used the URL from the repo I just created, but you should use the URL of your own repository:</p>
<pre><code>$ git clone git@github.com:johnmosesman/practical-git-tutorial.git
Cloning into <span class="hljs-string">'practical-git-tutorial'</span>...
remote: Enumerating objects: <span class="hljs-number">6</span>, done.
remote: Counting objects: <span class="hljs-number">100</span>% (<span class="hljs-number">6</span>/<span class="hljs-number">6</span>), done.
remote: Compressing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">3</span>/<span class="hljs-number">3</span>), done.
remote: Total <span class="hljs-number">6</span> (delta <span class="hljs-number">0</span>), reused <span class="hljs-number">0</span> (delta <span class="hljs-number">0</span>), pack-reused <span class="hljs-number">0</span>
Receiving objects: <span class="hljs-number">100</span>% (<span class="hljs-number">6</span>/<span class="hljs-number">6</span>), done.
</code></pre><blockquote>
<p><strong>Note:</strong> commands to be run in your terminal will be prefixed with a <code>$</code>.</p>
</blockquote>
<p>We'll go into more detail about what <code>git clone</code> does soon, but for now just know that it downloads the project and places it in a folder in your current working directory.</p>
<p>Next let's change into the new directory using <code>cd</code>:</p>
<pre><code>$ cd practical-git-tutorial/
/practical-git-tutorial (main)$
</code></pre><p>We've changed into the folder (which is just like any other folder), and your terminal may show you something alongside the directory name: <code>(main)</code>.</p>
<h2 id="heading-git-branches">Git branches</h2>
<p>This <code>(main)</code> means that we are currently on a <strong>branch</strong> called <code>main</code>. You can think of a Git branch as a copy of the project <em>at a specific point in time</em> that can be changed independently of other branches.</p>
<p>For example, if we used Git to track writing a book, we might have branches that look like this:</p>
<ul>
<li><code>main</code> branch</li>
<li><code>table-of-contents</code> branch</li>
<li><code>chapter-1</code> branch</li>
<li><code>chapter-2</code> branch</li>
<li>etc.</li>
</ul>
<p>The <code>main</code> branch is, well, the "main" branch—the place where we're going to combine all of the contents of the book into one finalized, finished book.</p>
<p>We can create other branches to separate and track specific pieces of work. </p>
<p>If I was working on Chapter 1 and you were working on Chapter 2, we could create two difference branches, <code>chapter-1</code> and <code>chapter-2</code>—effectively two different copies of the current status of the book. </p>
<p>We could then both work on our respective chapters without stepping on each others' toes or changing the contents out from under each other—we both have our own working copy that are separate from each other.</p>
<p>When either of us are finished with our chapter, we can add the contents of our chapter branch back into the <code>main</code> branch. When we're both finished, the <code>main</code> branch will contain both Chapter 1 and Chapter 2.</p>
<p>However, there are times where you <em>will</em> overwrite or change the same piece of content as someone else and we'll have to figure out how to settle those differences—and we'll see that soon.</p>
<blockquote>
<p><strong>Note:</strong> depending on the project <a target="_blank" href="https://github.com/github/renaming">you may see a branch</a> named <code>master</code> instead of <code>main</code>. It doesn't have any functional difference, just type <code>master</code> vs <code>main</code> depending on what's in your project.</p>
</blockquote>
<h2 id="heading-how-to-check-the-status-of-a-git-project">How to check the status of a Git project</h2>
<p>One thing we'll do often is check the status of our project. What changes have been made and what do we want to do with them?</p>
<p>To view the status of our project we use <code>git status</code>:</p>
<pre><code>(main)$ git status
On branch main
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.

nothing to commit, working tree clean
</code></pre><p>There's a few things in the result of this command, so let's break those down.</p>
<p>The first thing <code>git status</code> tells us is we're on the <code>main</code> branch:</p>
<pre><code> On branch main
</code></pre><p>The second sentence is a little more interesting:</p>
<pre><code>Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.
</code></pre><p>Git is telling us that our branch is "up to date" with something called <code>origin/main</code>.</p>
<p><code>origin</code> is a new concept known as a <strong>remote</strong>. A remote is a "remote source" different from your local machine.</p>
<p>In this project we have our local copy of the project, but we can also add remote sources that we can collaborate with. After all, that is one of the biggest benefits of Git: controlled collaboration with others.</p>
<p>Continuing with our book-writing example, if I write Chapter 1 on my machine and you write Chapter 2 on your machine, we could both add each other's computers as "remotes" and send and receive changes from each other.</p>
<p>In practice, the programming community at large has decided that it is best to have a <strong>single source of truth</strong> for code. One place that is always "correct" about what the current state of the codebase is. By convention, we call this place the <strong>origin</strong>.</p>
<p>In this case, GitHub is our "origin."</p>
<p>In fact, we can see this by running the command <code>git remote -v</code> (<code>-v</code> for "verbose"):</p>
<pre><code>(main)$ git remote -v
origin  git@github.com:johnmosesman/practical-git-tutorial.git (fetch)
origin  git@github.com:johnmosesman/practical-git-tutorial.git (push)
</code></pre><p>This command lists all of our remotes. From the result we can see that we have a remote named <code>origin</code>, and the Git URL of this remote points to our repo on Github.com. This remote was automatically setup for us when we ran <code>git clone</code>.</p>
<p>So coming back to this statement in the result of <code>git status</code>:</p>
<p><code>Your branch is up to date with 'origin/main'.</code></p>
<p>When we asked for the status of our project, Git told us that our local <code>main</code> branch is up to date with the <code>main</code> branch at our origin—which is GitHub. </p>
<p>In fact, <code>git clone</code> automatically created a <code>main</code> branch for us locally because it saw that the origin we cloned from had a branch called <code>main</code> as its primary branch.</p>
<p>Basically, there are no changes on our local machine different from GitHub or vice versa—our local <code>main</code> branch and the GitHub <code>main</code> branch are identical.</p>
<p>As we make changes we'll see this message change to reflect the differences in our local repository and the origin (GitHub) repository.</p>
<p>The final message from <code>git status</code> is about the state of the local project: </p>
<pre><code>nothing to commit, working tree clean
</code></pre><p>We'll go into more detail here as we make changes, but this message is basically saying we haven't done anything—so no changes to report.</p>
<p>To summarize the result of <code>git status</code>:</p>
<ul>
<li>We're on branch <code>main</code></li>
<li>Our local <code>main</code> branch is identical to the <code>origin</code>'s (GitHub's) <code>main</code> branch</li>
<li>We haven't made any changes to the project yet</li>
</ul>
<h2 id="heading-how-to-make-our-first-commit">How to make our first commit</h2>
<p>Now that we understand the initial state of our project, let's make some changes and look at the result.</p>
<p>Continuing with our book analogy, let's make a new file called <code>chapter-1.txt</code> and insert a sentence into it.</p>
<p>(You can use the terminal commands below, or create and edit the file in any text editor you choose—it doesn't matter.)</p>
<pre><code>(main)$ touch chapter<span class="hljs-number">-1.</span>txt
(main)$ echo <span class="hljs-string">"Chapter 1 - The Beginning"</span> &gt;&gt; chapter<span class="hljs-number">-1.</span>txt
(main)$ cat chapter<span class="hljs-number">-1.</span>txt
Chapter <span class="hljs-number">1</span> - The Beginning
</code></pre><p>The commands above make a new file called <code>chapter-1.txt</code> using <code>touch</code>, insert the sentence "Chapter 1 - The Beginning" using <code>echo</code> and the <code>&gt;&gt;</code> operator, and, to double-check our work, show the contents of the file using <code>cat</code>.</p>
<p>The result is a simple text file with one sentence in it.</p>
<p>Let's run <code>git status</code> again and see the difference in its output:</p>
<pre><code>(main)$ git status
On branch main
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.

Untracked files:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to include <span class="hljs-keyword">in</span> what will be committed)
        chapter<span class="hljs-number">-1.</span>txt

nothing added to commit but untracked files present (use <span class="hljs-string">"git add"</span> to track)
</code></pre><p>Here we see a different output than before. We see a section describing "Untracked files," and our new file <code>chapter-1.txt</code> is listed there.</p>
<p>Before Git will start tracking changes to a file we first have to tell Git to track it—and as the bottom of the message states—we can use <code>git add</code> to do that:</p>
<pre><code>(main)$ git add chapter<span class="hljs-number">-1.</span>txt
</code></pre><p>(Instead of specifying the name of the file for <code>git add</code>, you can use a period (<code>.</code>) to add all of the changes in the directory.)</p>
<p>Let's check the status again:</p>
<pre><code>(main)$ git status
On branch main
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.

Changes to be committed:
  (use <span class="hljs-string">"git restore --staged &lt;file&gt;..."</span> to unstage)
        <span class="hljs-keyword">new</span> file:   chapter<span class="hljs-number">-1.</span>txt

<span class="hljs-attr">john</span>:~<span class="hljs-regexp">/code/</span>practical-git-tutorial (main)$
</code></pre><p>The message has changed again. It nows says that we have some changes that are ready to be "committed."</p>
<p>A <strong>commit</strong> in Git is a saved chunk of work, but it's a little different from the same save you would use to save a text file in a text editor.</p>
<p>You can think of a commit as a <em>completed idea or unit of work.</em></p>
<p>For example, if we were continuing to write the contents of Chapter 1 in the book, it might look like this:</p>
<ul>
<li>Write the title of the chapter. <em><em>click save in our editor</em></em></li>
<li>Write the first paragraph of the chapter. <em><em>click save in our editor</em></em></li>
<li>Write the second paragraph of the chapter. <em><em>click save again</em></em></li>
<li>Write the final paragraph of the chapter. <em><em>click save again</em></em></li>
</ul>
<p>Here, we've "saved" the document four times, but at the end of those four saves we now have the first draft of our chapter, and that draft is one "unit of work." </p>
<p>We want to save this file on our computer, but we also want to signify that this is a unit of completed work—even if it's just a draft. It's a chunk of work worth holding onto. We may want to return to it in the future, go back and edit it, or merge this draft into the current draft of the entire book.</p>
<p>To do this, we create a new commit to signify this milestone. Each commit gets its own unique identifier, and the order of the commits are preserved.</p>
<p>To commit our changes, they must first be added to the <strong>staging area</strong> by using <code>git add</code>.</p>
<p>(We'll talk more about the staging area soon.)</p>
<p>Next, we need to finalize the commit by using <code>git commit</code>.</p>
<p>It's best practice to provide a detailed message of <em>what changes</em> you made—and more importantly—<em>why</em> you are committing these changes.</p>
<p>Once the commit history becomes hundreds or thousands of commits long, it becomes near impossible to understand <em>why</em> a change was made without a good commit message. Git will show us what files changed and what the changes were, but the <em>meaning of those changes</em> is up to us to provide.</p>
<p>Let's commit the new file we made with a commit message by using the <code>-m</code> or "message" flag:</p>
<pre><code>(main)$ git commit -m <span class="hljs-string">"New chapter 1 file with chapter heading"</span>
[main a8f8b95] New chapter <span class="hljs-number">1</span> file <span class="hljs-keyword">with</span> chapter heading
 <span class="hljs-number">1</span> file changed, <span class="hljs-number">1</span> insertion(+)
 create mode <span class="hljs-number">100644</span> chapter<span class="hljs-number">-1.</span>txt
</code></pre><p>We've now committed that chunk of work, and we can see that by viewing the Git log via <code>git log</code>:</p>
<pre><code>(main)$ git log
commit a8f8b95f19105fe10ed144fead9cab84520181e3 (HEAD -&gt; main)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Fri Mar <span class="hljs-number">19</span> <span class="hljs-number">12</span>:<span class="hljs-number">27</span>:<span class="hljs-number">35</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    New chapter <span class="hljs-number">1</span> file <span class="hljs-keyword">with</span> chapter heading

commit <span class="hljs-number">2592324</span>fae9c615a96f856a0d8b8fe1d2d8439f8 (origin/main, origin/HEAD)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@users.noreply.github.com&gt;
<span class="hljs-built_in">Date</span>:   Wed Mar <span class="hljs-number">17</span> <span class="hljs-number">08</span>:<span class="hljs-number">48</span>:<span class="hljs-number">25</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Update README.md

commit <span class="hljs-number">024</span>ea223ee4055ae82ee31fc605bbd8a5a3673a0
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@users.noreply.github.com&gt;
<span class="hljs-built_in">Date</span>:   Wed Mar <span class="hljs-number">17</span> <span class="hljs-number">08</span>:<span class="hljs-number">48</span>:<span class="hljs-number">10</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Initial commit
</code></pre><p>Looking at this log, we see that there are three commits in the project history. </p>
<p>The latest commit is the one we just made. We can see the same commit message we just used: <em>"New chapter 1 file...".</em></p>
<p>There are also two previous commits: one when I initialized the project and another when I updated the <code>README.md</code> file on GitHub.</p>
<p>Notice that each commit has a long string of numbers and characters associated with it:</p>
<pre><code>commit a8f8b95f19105fe10ed144fead9cab84520181e3 (HEAD -&gt; main)
</code></pre><p>This string of characters and numbers is called the <a target="_blank" href="https://en.wikipedia.org/wiki/SHA-1">SHA</a>—it's the unique ID generated by a hashing algorithm for this commit. Just take note of these for now—we'll come back to this soon.</p>
<p>We also see two other interesting things in the log after the commit SHAs: </p>
<ul>
<li><code>(HEAD -&gt; main)</code> next to our latest commit</li>
<li>And <code>(origin/main, origin/HEAD)</code> next to the commit before that one.</li>
</ul>
<p>This information tells us the <em>current status of our branches and remotes</em> (as far as we know—but more on this later).</p>
<p>For the latest commit, we see that the <code>HEAD</code> (aka "where we are now" in the project history) is pointing at our <em>local</em> <code>main</code> branch—represented by <code>HEAD -&gt; main</code>. </p>
<p>This makes sense because we just made that commit, and we haven't done anything else—we're still at the point in time where we made that commit.</p>
<p>If we look at the previous commit starting with <code>25923</code>, we see <code>(origin/main, origin/HEAD)</code>. This tells us that, <em>on the origin (aka GitHub)</em>, GitHub's <code>HEAD</code> or "current place" is on our previous commit.</p>
<p>Basically, our local machine thinks the latest change for local <code>main</code> branch is the commit where we added Chapter 1, and our local machine also thinks that <em>on GitHub</em> the latest change is the commit where I updated the README before I wrote this post.</p>
<p>And this makes sense—we haven't told GitHub about the newest commit we made. GitHub still thinks that the repo is up to date with what it has seen.</p>
<p>Now let's push up our new commit to GitHub.</p>
<h2 id="heading-how-to-push-up-our-first-commit-to-github">How to push up our first commit to GitHub</h2>
<p>We have a new commit on our local machine and we need to update our "source of truth"—the <code>origin</code> remote—aka GitHub.</p>
<p>We're currently on the <code>main</code> branch locally, so we need to tell GitHub to update its own <code>main</code> with the new commit that we made.</p>
<p>To do that we use the <code>git push</code> command and we can specify <em>where we want to push</em> and <em>what branch we want to push to</em>.</p>
<pre><code>(main)$ git push origin main
Enumerating objects: <span class="hljs-number">4</span>, done.
Counting objects: <span class="hljs-number">100</span>% (<span class="hljs-number">4</span>/<span class="hljs-number">4</span>), done.
Delta compression using up to <span class="hljs-number">16</span> threads
Compressing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">2</span>/<span class="hljs-number">2</span>), done.
Writing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">3</span>/<span class="hljs-number">3</span>), <span class="hljs-number">326</span> bytes | <span class="hljs-number">326.00</span> KiB/s, done.
Total <span class="hljs-number">3</span> (delta <span class="hljs-number">0</span>), reused <span class="hljs-number">0</span> (delta <span class="hljs-number">0</span>)
To github.com:johnmosesman/practical-git-tutorial.git
   <span class="hljs-number">2592324.</span>.a8f8b95  main -&gt; main
</code></pre><p>Here we pushed to the <code>origin</code> remote (GitHub) and to the <code>main</code> branch.</p>
<p>The output tells us about some file operations Git did to do that, and the last line of the output tells us which commits it pushed and to where:</p>
<pre><code>To github.com:johnmosesman/practical-git-tutorial.git
   <span class="hljs-number">2592324.</span>.a8f8b95  main -&gt; main
</code></pre><p>Here it shows us that we pushed our <code>main</code> branch to GitHub's <code>main</code> branch.</p>
<p>If we look back at the <code>git log</code> output we'll notice that both our local and <code>origin</code> point to the same commit now:</p>
<pre><code>(main)$ git log
commit f5b6e2f18f742e2b851e38f52a969dd921f72d2f (HEAD -&gt; main, origin/main, origin/HEAD)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Mon Mar <span class="hljs-number">22</span> <span class="hljs-number">10</span>:<span class="hljs-number">07</span>:<span class="hljs-number">35</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Added the intro line to chapter <span class="hljs-number">1</span>
</code></pre><p>In short, on <code>origin</code> (GitHub) the <code>main</code> branch (also written as <code>origin/main</code>) has now placed our new commit as the latest commit in the history.</p>
<p>If we were working with other collaborators, they could now pull down our newest change from GitHub and begin editing the Chapter 1 as well.</p>
<h2 id="heading-how-to-add-another-commit-in-git">How to add another commit in Git</h2>
<p>Before we start collaborating with others, let's make another small change to see what happens when we edit an existing file.</p>
<p>Let's add another line into our Chapter 1 file:</p>
<pre><code>(main)$ echo <span class="hljs-string">"It was the best of times, it was the worst of times"</span> &gt;&gt; chapter<span class="hljs-number">-1.</span>txt
(main)$ cat chapter<span class="hljs-number">-1.</span>txt
Chapter <span class="hljs-number">1</span> - The Beginning
It was the best <span class="hljs-keyword">of</span> times, it was the worst <span class="hljs-keyword">of</span> times
</code></pre><p>Using <code>cat</code> we can see that our file now contains two lines.</p>
<p>Let's look at the status of our Git repo again:</p>
<pre><code>(main)$ git status
On branch main
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.

Changes not staged <span class="hljs-keyword">for</span> commit:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to update what will be committed)
  (use <span class="hljs-string">"git restore &lt;file&gt;..."</span> to discard changes <span class="hljs-keyword">in</span> working directory)
        <span class="hljs-attr">modified</span>:   chapter<span class="hljs-number">-1.</span>txt

no changes added to commit (use <span class="hljs-string">"git add"</span> and/or <span class="hljs-string">"git commit -a"</span>)
</code></pre><p>Starting from the top, we'll notice the output says <code>Your branch is up to date with 'origin/main'.</code></p>
<p>This might seem odd to you since we just changed a file, but Git is only comparing <em>the commits</em> we've made against the commits in <code>origin/main</code>.</p>
<p>The next section of the output explains it a little more:</p>
<pre><code>Changes not staged <span class="hljs-keyword">for</span> commit:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to update what will be committed)
  (use <span class="hljs-string">"git restore &lt;file&gt;..."</span> to discard changes <span class="hljs-keyword">in</span> working directory)
        <span class="hljs-attr">modified</span>:   chapter<span class="hljs-number">-1.</span>txt
</code></pre><p>Here Git tells us that we have "changes not staged for commit."</p>
<p>Before we can commit a set of changes, we first have to <strong>stage</strong> them.</p>
<h3 id="heading-how-to-stage-changes-in-git">How to stage changes in Git</h3>
<p>To illustrate the usefulness of the staging area, let's first stage our changes by using <code>git add</code>:</p>
<pre><code>(main)$ git add .
(main)$ git status
On branch main
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.

Changes to be committed:
  (use <span class="hljs-string">"git restore --staged &lt;file&gt;..."</span> to unstage)
        <span class="hljs-attr">modified</span>:   chapter<span class="hljs-number">-1.</span>txt
</code></pre><p>These changes are now ready to be committed, but before we commit them let's add another change into our <code>chapter-1.txt</code> file.</p>
<p>I'm going to replace the contents of <code>chapter-1.txt</code> entirely with new text:</p>
<blockquote>
<p><strong>Note:</strong> I'm using <code>&gt;</code> here instead of <code>&gt;&gt;</code> which will replace the contents of the file instead of appending to the file.</p>
</blockquote>
<pre><code>(main)$ echo <span class="hljs-string">"New file contents"</span> &gt; chapter<span class="hljs-number">-1.</span>txt

(main)$ cat chapter<span class="hljs-number">-1.</span>txt
New file contents

(main)$ git status
On branch main
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.

Changes to be committed:
  (use <span class="hljs-string">"git restore --staged &lt;file&gt;..."</span> to unstage)
        <span class="hljs-attr">modified</span>:   chapter<span class="hljs-number">-1.</span>txt

Changes not staged <span class="hljs-keyword">for</span> commit:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to update what will be committed)
  (use <span class="hljs-string">"git restore &lt;file&gt;..."</span> to discard changes <span class="hljs-keyword">in</span> working directory)
        <span class="hljs-attr">modified</span>:   chapter<span class="hljs-number">-1.</span>txt
</code></pre><p>From the output we can see that we now have <em>staged</em> changes, and <em>not staged changes.</em> </p>
<p>While the file itself can only contain one thing, Git keeps track of both changes for us—even though they're changes to the same lines!</p>
<p>However, from the output above we can't really tell what those changes were—we just know that they exist.</p>
<p>To view these changes, we'll first look at the command line way (which I never use), and then a way that uses a GUI (which is 100% nicer).</p>
<h3 id="heading-how-to-view-the-git-diff">How to view the Git diff</h3>
<p>To view the changes, we need to look at the Git <strong>diff.</strong> </p>
<p>A <em>diff</em> (short for difference) is the difference between two sets of changes. Those changes could be anything from staged changes to not-staged changes to commits.</p>
<p>The command line way to do this is by using <code>git diff</code>.</p>
<p>We'll look at this output in our simple case here just for completeness' sake. But, as I mentioned before, we're interested in effective Git workflows, and once you get to changes of any decent size across multiple files this command line output just becomes not effective.</p>
<p>But for completeness, here it is:</p>
<pre><code>(main)$ git diff
diff --git a/chapter<span class="hljs-number">-1.</span>txt b/chapter<span class="hljs-number">-1.</span>txt
index <span class="hljs-number">0450</span>d87.<span class="hljs-number">.4</span>cbeaee <span class="hljs-number">100644</span>
--- a/chapter<span class="hljs-number">-1.</span>txt
+++ b/chapter<span class="hljs-number">-1.</span>txt
@@ <span class="hljs-number">-1</span>,<span class="hljs-number">2</span> +<span class="hljs-number">1</span> @@
-Chapter <span class="hljs-number">1</span> - The Beginning
-It was the best <span class="hljs-keyword">of</span> times, it was the worst <span class="hljs-keyword">of</span> times
+New file contents
</code></pre><p>My terminal attempts to colorize this output to help with readability, but the important parts to notice here is it tells us what file we're diffing, <code>chapter-1.txt</code>, and at the bottom it shows us the actual differences. Let's key in on those lines:</p>
<pre><code>-Chapter <span class="hljs-number">1</span> - The Beginning
-It was the best <span class="hljs-keyword">of</span> times, it was the worst <span class="hljs-keyword">of</span> times
+New file contents
</code></pre><p>The lines starting with a minus sign (<code>-</code>) are lines we deleted entirely or in part, and the lines starting with a <code>+</code> sign represent lines added entirely or in part.</p>
<p>Now, with multiple files and many lines changed this output becomes unwieldy—fast. There is a better way, and even almost ten years into my programming career I still use a simple GUI program to help look at and manage diffs.</p>
<p>The program I use is called <a target="_blank" href="http://gitx.frim.nl/">GitX</a>, and it's an old and outdated piece of software that's not even really being maintained anymore. However, I just use it to view and manage file diffs—so it works for me. </p>
<p>I wouldn't particularly recommend this one, but it is free. Although I've never used it, the <a target="_blank" href="https://desktop.github.com/">GitHub Desktop client</a> is probably a good choice.</p>
<p>Now with that little aside out of the way, here's what the diff looks like in my tool.</p>
<p>To start, the staged changes on the right-hand side show our original add of the second sentence:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/staged_changes.png" alt="Image" width="600" height="400" loading="lazy">
<em>Staged changes in GitX</em></p>
<p>In the unstaged changes on the left-hand side, we see the removal of those two lines entirely and the addition of a new line:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/unstaged_changes.png" alt="Image" width="600" height="400" loading="lazy">
<em>Unstaged changes in GitX</em></p>
<p>This corresponds to the file replace command we ran.</p>
<p>It is so much easier to understand the diff in a GUI program. This program also allows me to quickly switch between staging and un-staging files by just dragging them around. I can even stage or un-stage individual lines in a file back and forth as well.</p>
<p>There's no bonus points for using the command line vs a GUI program. Use whatever gets the job done for you.</p>
<p>Now that we've seen how the staging area and Git diffs work, let's discard our non-staged changes so we can get back to committing our first change.</p>
<p>In my GUI program I can right-click the file and click "Discard changes", but I'll show the command line version here as well.</p>
<p>The output of our last <code>git status</code> actually showed us how to do this by using <code>git restore</code>. We can pass the file path or just a <code>.</code> for the whole directory:</p>
<pre><code>(main)$ git restore .
</code></pre><p>If we check the status again we're back to just our staged changes, and we can continue.</p>
<blockquote>
<p><strong>Note:</strong> Git only commits changes that are staged, so we could have left those unstaged changes in our working directory and it wouldn't interfere with the committing process.  </p>
<p>However, it would make our future changes more cumbersome to deal with—so it makes sense to discard those changes to keep our working directory in good shape.</p>
</blockquote>
<p>Now let's finally commit these changes with a message about what we did:</p>
<pre><code>(main)$ git commit -m <span class="hljs-string">"Added the intro line to chapter 1"</span>
[main f5b6e2f] Added the intro line to chapter <span class="hljs-number">1</span>
 <span class="hljs-number">1</span> file changed, <span class="hljs-number">1</span> insertion(+)
</code></pre><p>Checking the status once again shows us that our branch is "ahead of 'origin/main' by 1 commit":</p>
<pre><code>(main)$ git status
On branch main
Your branch is ahead <span class="hljs-keyword">of</span> <span class="hljs-string">'origin/main'</span> by <span class="hljs-number">1</span> commit.
  (use <span class="hljs-string">"git push"</span> to publish your local commits)

nothing to commit, working tree clean
</code></pre><p>Finally let's push up our change:</p>
<pre><code>(main)$ git push origin main
</code></pre><h2 id="heading-how-to-collaborate-with-others-in-git">How to collaborate with others in Git</h2>
<p>So far we've been looking at the simplest use case: working by ourselves on one branch.</p>
<p>In reality, we'll usually be working with multiple people working on multiple different branches. This is the real power of Git after all: a system to collaborate and track changes over time amongst many collaborators.</p>
<p>For now, let's continue working as if we're the only person on the project, but let's adjust our workflow a little bit to prepare for when that's not the case.</p>
<p>In general, it's best practice to <em>not</em> work directly on the <code>main</code> branch. </p>
<p>The <code>main</code> branch is supposed to be the "source of truth" for the project—changes to it should be carefully reviewed. Any change in <code>origin/main</code> becomes the new "source of truth" for anyone else working on the project, so we shouldn't just change it without some thought and review by others.</p>
<p>Instead of working on <code>main</code> directly, let's <em>branch</em> off of <code>main</code> into our own <strong>feature branch</strong>, and then <strong>merge</strong> those changes back into <code>main</code>.</p>
<p>That's a lot of new terminology, so let's take it one step at a time.</p>
<h3 id="heading-feature-branches-in-git">Feature branches in Git</h3>
<p>To begin, let's branch off of <code>main</code> and create our own feature branch to work on.</p>
<p>When you create a branch off of another branch, you create a copy of that branch <em>at that point in time.</em> You can now change this new branch independently of the original branch.</p>
<p>To try this out, let's make a new branch called <code>chapter-2</code>. To do this we use <code>git checkout</code> with the <code>-b</code> flag and the name we want the new branch to have:</p>
<pre><code>(main)$ git checkout -b chapter<span class="hljs-number">-2</span>
Switched to a <span class="hljs-keyword">new</span> branch <span class="hljs-string">'chapter-2'</span>
(chapter<span class="hljs-number">-2</span>)$
</code></pre><p>Notice that the terminal now shows us on the <code>chapter-2</code> branch. Changes on the <code>chapter-2</code> branch will not affect the <code>main</code> branch at all. We essentially have a new playground to make whatever changes we want to make without affecting <code>main</code>.</p>
<p>There are interesting things happening under the hood here, but for the purpose of this tutorial we just need to know that to "checkout" something in Git means to "change my local project to look exactly like the project looked <em>at some specific point in time.</em>" You can think of a branch as a pointer to a specific timeline of the Git history.</p>
<p>There's a lot more happening here, but that definition should be good enough for now.</p>
<p>So we have a new branch, and for now that new branch is identical to <code>main</code> (we haven't made any changes yet).</p>
<p>Next let's repeat what we've already done before and create a new file called <code>chapter-2.txt</code>, give it some content, and commit it:</p>
<pre><code>(chapter<span class="hljs-number">-2</span>)$ touch chapter<span class="hljs-number">-2.</span>txt
(chapter<span class="hljs-number">-2</span>)$ echo <span class="hljs-string">"Chapter 2 - The next chapter"</span> &gt;&gt; chapter<span class="hljs-number">-2.</span>txt

(chapter<span class="hljs-number">-2</span>)$ git status
On branch chapter<span class="hljs-number">-2</span>
Untracked files:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to include <span class="hljs-keyword">in</span> what will be committed)
        chapter<span class="hljs-number">-2.</span>txt

nothing added to commit but untracked files present (use <span class="hljs-string">"git add"</span> to track)

(chapter<span class="hljs-number">-2</span>)$ git add .

(chapter<span class="hljs-number">-2</span>)$ git commit -m <span class="hljs-string">"Creates chapter 2 and adds the topic sentence"</span>
[chapter<span class="hljs-number">-2</span> <span class="hljs-number">741822</span>a] Creates chapter <span class="hljs-number">2</span> and adds the topic sentence
 <span class="hljs-number">1</span> file changed, <span class="hljs-number">1</span> insertion(+)
 create mode <span class="hljs-number">100644</span> chapter<span class="hljs-number">-2.</span>txt
</code></pre><p>Nothing new in there—just the same thing we did for Chapter 1.</p>
<p>Now that we have a new commit on our <code>chapter-2</code> branch, let's look the Git log and compare this new branch to <code>main</code>:</p>
<pre><code>(chapter<span class="hljs-number">-2</span>)$ git log
commit <span class="hljs-number">741822</span>a9fd7b15b6e3caf437dd0617fabf918449 (HEAD -&gt; chapter<span class="hljs-number">-2</span>)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Mon Mar <span class="hljs-number">22</span> <span class="hljs-number">10</span>:<span class="hljs-number">33</span>:<span class="hljs-number">26</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Creates chapter <span class="hljs-number">2</span> and adds the topic sentence

commit f5b6e2f18f742e2b851e38f52a969dd921f72d2f (origin/main, origin/HEAD, main)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Mon Mar <span class="hljs-number">22</span> <span class="hljs-number">10</span>:<span class="hljs-number">07</span>:<span class="hljs-number">35</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Added the intro line to chapter <span class="hljs-number">1</span>

commit a8f8b95f19105fe10ed144fead9cab84520181e3
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Fri Mar <span class="hljs-number">19</span> <span class="hljs-number">12</span>:<span class="hljs-number">27</span>:<span class="hljs-number">35</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    New chapter <span class="hljs-number">1</span> file <span class="hljs-keyword">with</span> chapter heading
...
</code></pre><p>We'll notice in the log that our latest commit is shown at the top, and our <code>HEAD</code> is again different from our <code>origin</code>. This again makes sense—we've made changes locally that aren't in GitHub.</p>
<p>Now we need to get our new changes into the <code>main</code> branch.</p>
<h2 id="heading-git-workflows-for-collaboration">Git workflows for collaboration</h2>
<p>There are a couple of ways to get our new Chapter 2 into the <code>main</code> branch and into GitHub, and the way we choose depends on the project and what workflow we're using to collaborate with others.</p>
<p>First let's talk about a couple different workflows we could use.</p>
<p>The first one is the most straightforward:</p>
<ol>
<li>Merge changes from <code>chapter-2</code> into our local <code>main</code> branch</li>
<li>Push local <code>main</code> branch to <code>origin/main</code></li>
</ol>
<p>The second way is a little more complicated:</p>
<ul>
<li>Push our local <code>chapter-2</code> branch to origin (this creates a new branch on <code>origin</code> called <code>origin/chapter-2</code>)</li>
<li>Merge <code>origin/chapter-2</code> into <code>origin/main</code> on GitHub</li>
<li>Pull down the new changes from <code>origin/main</code> into our local <code>main</code></li>
</ul>
<p>The first workflow is definitely easier, and it is something I would use if I was working on this project by myself without any other collaborators.</p>
<p>However, if I had collaborators, I wouldn't want to push directly to the <code>main</code> branch from my local. By doing so I would be changing and taking control of the history of the project solely on my own changes—without any input or review from collaborators.</p>
<p>For this reason, if there were multiple people working on the same project, I would use the second workflow because it is a better collaboration process for the team.</p>
<p>That being said, we'll go over both workflows, and let's start with the first one which is less complicated.</p>
<h2 id="heading-how-to-merge-a-branch-in-git">How to merge a branch in Git</h2>
<p>When you want to combine the contents of two branches into one in Git, there are a few methods of doing so. The first and probably simplest way is to do a <strong>merge</strong>.</p>
<p>A merge, like it sounds, tries to take the contents of one branch and apply (or "merge in") those changes into another branch.</p>
<p>In our scenario, we want to take the contents of the <code>chapter-2</code> branch and <em>merge them into</em> <code>main</code>. Said another way, we want to take the current state of <code>main</code> and add in our changes from the <code>chapter-2</code> branch.</p>
<p>We can do this by using <code>git merge</code>, and we'll look at the result of it afterwards.</p>
<p>The first thing we need to do is be on the primary branch that we want to merge changes <em>into.</em> Since we want <code>main</code> to absorb the changes from <code>chapter-2</code>, we first need to be on the <code>main</code> branch.</p>
<p>To switch back to the <code>main</code> branch, we can again use <code>git checkout</code> and specify the branch name of <code>main</code>. This time we don't use the <code>-b</code> flag because we want to switch to an existing branch and not create a new one:</p>
<pre><code>(chapter<span class="hljs-number">-2</span>)$ git checkout main
Switched to branch <span class="hljs-string">'main'</span>
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.
(main)$
</code></pre><p>We're now back on the <code>main</code> branch, and we get a quick status message saying we're up to date with <code>origin/main</code>.</p>
<p>Next, let's merge our <code>chapter-2</code> branch into <code>main</code>:</p>
<pre><code>(main)$ git merge chapter<span class="hljs-number">-2</span>
Updating f5b6e2f.<span class="hljs-number">.741822</span>a
Fast-forward
 chapter<span class="hljs-number">-2.</span>txt | <span class="hljs-number">1</span> +
 <span class="hljs-number">1</span> file changed, <span class="hljs-number">1</span> insertion(+)
 create mode <span class="hljs-number">100644</span> chapter<span class="hljs-number">-2.</span>txt
</code></pre><p>Let's look at the Git log again to see the result:</p>
<pre><code>(main)$ git log
commit <span class="hljs-number">741822</span>a9fd7b15b6e3caf437dd0617fabf918449 (HEAD -&gt; main, chapter<span class="hljs-number">-2</span>)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Mon Mar <span class="hljs-number">22</span> <span class="hljs-number">10</span>:<span class="hljs-number">33</span>:<span class="hljs-number">26</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Creates chapter <span class="hljs-number">2</span> and adds the topic sentence

commit f5b6e2f18f742e2b851e38f52a969dd921f72d2f (origin/main, origin/HEAD)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Mon Mar <span class="hljs-number">22</span> <span class="hljs-number">10</span>:<span class="hljs-number">07</span>:<span class="hljs-number">35</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Added the intro line to chapter <span class="hljs-number">1</span>

...
</code></pre><p>We can see that our <code>main</code> branch now contains the new commit from <code>chapter-2</code>, and that our <code>origin</code> is still at the previous commit (as we haven't updated <code>origin</code> yet).</p>
<p>Finally, let's push our changes up to <code>origin/main</code>:</p>
<pre><code>(main)$ git push origin main
Total <span class="hljs-number">0</span> (delta <span class="hljs-number">0</span>), reused <span class="hljs-number">0</span> (delta <span class="hljs-number">0</span>)
To github.com:johnmosesman/practical-git-tutorial.git
   f5b6e2f.<span class="hljs-number">.741822</span>a  main -&gt; main
</code></pre><p>We've successfully merge our <code>chapter-2</code> branch, and pushed that change up to GitHub!</p>
<p>As a final cleanup step, let's delete the <code>chapter-2</code> feature branch as it has already been merged into <code>main</code>:</p>
<pre><code>(main)$ git branch -d chapter<span class="hljs-number">-2</span>
Deleted branch chapter<span class="hljs-number">-2</span> (was <span class="hljs-number">741822</span>a).
</code></pre><blockquote>
<p><strong>Note:</strong> the <code>git branch</code> command without a branch name argument will list all of the branches you have locally.  </p>
<p>Adding the <code>-d</code> flag and a branch name deletes the branch passed in.</p>
</blockquote>
<h2 id="heading-pull-request-workflow">Pull request workflow</h2>
<p>To work through our collaboration workflow, let's repeat the same thing we've done with Chapter 1 &amp; 2 on a new branch called <code>chapter-3</code>:</p>
<p>(Now would be a good time to try this on your own!)</p>
<pre><code>(main)$ git checkout -b chapter<span class="hljs-number">-3</span>
(chapter<span class="hljs-number">-3</span>)$ touch chapter<span class="hljs-number">-3.</span>txt
(chapter<span class="hljs-number">-3</span>)$ echo <span class="hljs-string">"Chapter 3 - The End?"</span> &gt;&gt; chapter<span class="hljs-number">-3.</span>txt
(chapter<span class="hljs-number">-3</span>)$ git add .
(chapter<span class="hljs-number">-3</span>)$ git commit -m <span class="hljs-string">"Adds Chapter 3"</span>
</code></pre><p>Now we have a new commit on a new branch called <code>chapter-3</code>.</p>
<p>Let's review how we're going to get this new branch merged into <code>main</code> <em>without acting directly on <code>main</code> ourselves:</em></p>
<ul>
<li>Push our local <code>chapter-3</code> branch to origin (this creates a new branch on <code>origin</code> called <code>origin/chapter-3</code>)</li>
<li>Merge <code>origin/chapter-3</code> into <code>origin/main</code> on GitHub</li>
<li>Pull down the new changes from <code>origin/main</code> into our local <code>main</code></li>
</ul>
<p>A couple more steps—but none that are too complicated.</p>
<p>The first step is to push our new branch to GitHub. Since this branch doesn't exist yet on GitHub, GitHub will make a new branch for us that is a copy of what we pushed:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>)$ git push origin chapter<span class="hljs-number">-3</span>
Enumerating objects: <span class="hljs-number">4</span>, done.
Counting objects: <span class="hljs-number">100</span>% (<span class="hljs-number">4</span>/<span class="hljs-number">4</span>), done.
Delta compression using up to <span class="hljs-number">16</span> threads
Compressing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">2</span>/<span class="hljs-number">2</span>), done.
Writing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">3</span>/<span class="hljs-number">3</span>), <span class="hljs-number">299</span> bytes | <span class="hljs-number">299.00</span> KiB/s, done.
Total <span class="hljs-number">3</span> (delta <span class="hljs-number">1</span>), reused <span class="hljs-number">0</span> (delta <span class="hljs-number">0</span>)
<span class="hljs-attr">remote</span>: Resolving deltas: <span class="hljs-number">100</span>% (<span class="hljs-number">1</span>/<span class="hljs-number">1</span>), completed <span class="hljs-keyword">with</span> <span class="hljs-number">1</span> local object.
remote:
remote: Create a pull request <span class="hljs-keyword">for</span> <span class="hljs-string">'chapter-3'</span> on GitHub by visiting:
remote:      https:<span class="hljs-comment">//github.com/johnmosesman/practical-git-tutorial/pull/new/chapter-3</span>
remote:
To github.com:johnmosesman/practical-git-tutorial.git
 * [<span class="hljs-keyword">new</span> branch]      chapter<span class="hljs-number">-3</span> -&gt; chapter<span class="hljs-number">-3</span>
</code></pre><p>Now that we have our branch on GitHub, we can create a <strong>pull request</strong> to be reviewed by our teammates.</p>
<p>GitHub even provides us with the URL to visit in our output above: <code>https://github.com/johnmosesman/practical-git-tutorial/pull/new/chapter-3</code></p>
<blockquote>
<p><strong>A couple notes:</strong> this next part shows GitHub's UI and process for pull requests, but this process should be very similar for other services (like GitLab, Bitbucket, etc.).  </p>
<p>Also keep in mind I'm using my own repo, so some of the URLs you see here will be different from yours.</p>
</blockquote>
<p>Visiting the URL above, we arrive at a page to open a new pull request. </p>
<p>We see a few things:</p>
<ul>
<li>A place to specify the name of the pull request (a topic sentence to easily understand what this PR is about)</li>
<li>A box for a description to explain the changes we made and any other context we want to provide (you can also add images, gifs, or videos here as well)</li>
<li>And below all of that is the list of files we changed and the changes in them (the diff).</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-24-at-10.22.13-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Opening a new pull request</em></p>
<p>Notice that the UI shows <code>base: main &lt;- compare: chapter-3</code>. This is GitHub telling us that we're setting the pull request to merge <code>chapter-3</code> <em>into</em> <code>main</code>.</p>
<p>Below the pull request description is the diff of the changes we made:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-24-at-10.26.42-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>The pull request diff</em></p>
<p>We'll notice that only the file <code>chapter-3.txt</code> is shown, and this is because it's the only file that we changed. </p>
<p>There are other files currently in our project (<code>chapter-1.txt</code>, <code>chapter-2.txt</code>), but those files didn't change so there's no need to show them.</p>
<p>We see the one line we inserted into <code>chapter-3.txt</code>—signified by a <code>+</code> sign at the start of the line and the green background which signifies an addition to the file.</p>
<p>After clicking "Create Pull Request" we're taken to the new PR we just made. </p>
<p>At this point we could assign a reviewer to the PR and have a back-and-forth discussion around the code by leaving comments on specific lines in the diff. After the code has been reviewed and we make any changes that need to be made, we're ready to merge.</p>
<p>For this sake of this tutorial we'll skip the review process, and just click the big green merge button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-24-at-10.39.55-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Merged pull request</em></p>
<p>And with that, our pull request has been merged into <code>main</code>!</p>
<h2 id="heading-how-to-bring-our-local-up-to-date">How to bring our local up to date</h2>
<p>We've now made a change to <code>origin/main</code> in a safe, controlled, and peer-reviewed way.</p>
<p>But, our local doesn't know anything about this change. Locally, Git still thinks we're on our <code>chapter-3</code> branch which isn't merged into <code>main</code>:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>)$ git log
commit <span class="hljs-number">085</span>ca1ce2d0010fdaa1c0ffc23ff880091ce1692 (HEAD -&gt; chapter<span class="hljs-number">-3</span>, origin/chapter<span class="hljs-number">-3</span>)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Tue Mar <span class="hljs-number">23</span> <span class="hljs-number">09</span>:<span class="hljs-number">19</span>:<span class="hljs-number">14</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Adds Chapter <span class="hljs-number">3</span>

commit <span class="hljs-number">741822</span>a9fd7b15b6e3caf437dd0617fabf918449 (origin/main, origin/HEAD, main)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Mon Mar <span class="hljs-number">22</span> <span class="hljs-number">10</span>:<span class="hljs-number">33</span>:<span class="hljs-number">26</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Creates chapter <span class="hljs-number">2</span> and adds the topic sentence

...
</code></pre><p>Our local shows <code>origin/main</code> on the previous commit starting with <code>741822</code>. We need to pull in the new information from our <code>origin</code> to update our local repository.</p>
<h3 id="heading-how-to-retrieve-remote-data">How to retrieve remote data</h3>
<p>As with many other things with Git, there are many different methods to accomplish the same task.</p>
<p>For our purposes, we'll look at a straightforward way that will work in the majority of cases.</p>
<p>To start, let's switch back to our <code>main</code> branch locally:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>)$ git checkout main
Switched to branch <span class="hljs-string">'main'</span>
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/main'</span>.
</code></pre><p>Our local thinks we're up to date with <code>origin/main</code> because we haven't asked the remote repository (<code>origin</code>) for new information since we pulled the project at the beginning using <code>git clone</code>.</p>
<p>Git repositories are not live-updating—they're just a snapshot of the history at a point in time. To receive any new information about the repository we have to ask for it again.</p>
<p>To retrieve any new information that has changed on the remote, we use <code>git fetch</code>:</p>
<pre><code>(main)$ git fetch
From github.com:johnmosesman/practical-git-tutorial
   <span class="hljs-number">741822</span>a.<span class="hljs-number">.10630</span>f2  main       -&gt; origin/main
</code></pre><p>The output shows us that <code>origin/main</code> is now pointing to a commit starting with <code>10630f2</code>. This commit prefix matches the SHA of the merge commit of our pull request.</p>
<p> There are a few ways to merge two branches into one another, and one of those ways is by creating a <strong>merge commit</strong>. That's what happened here.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/commit.png" alt="Image" width="600" height="400" loading="lazy">
<em>The merge commit of our PR</em></p>
<p>Our local repository now knows about the presence of these new commits, but we haven't done anything with them yet.</p>
<p>Running <code>git fetch</code> doesn't actually change any of our files—it just downloads new information from the remote about the status of the repo.</p>
<p>Now that our local repository is aware of the status of each branch (but hasn't <em>changed or updated</em> any of the branches), let's check our status again:</p>
<pre><code>(main)$ git status
Your branch is behind <span class="hljs-string">'origin/main'</span> by <span class="hljs-number">2</span> commits, and can be fast-forwarded.
  (use <span class="hljs-string">"git pull"</span> to update your local branch)
</code></pre><p>Our local now knows that our local <code>main</code> is behind <code>origin/main</code> by 2 commits (the commit from the <code>chapter-3</code> branch and the PR merge commit).</p>
<p>It also gives us the hint to use <code>git pull</code> to update our local branch:</p>
<pre><code>john:~<span class="hljs-regexp">/code/</span>practical-git-tutorial (main)$ git pull origin main
From github.com:johnmosesman/practical-git-tutorial
 * branch            main       -&gt; FETCH_HEAD
Updating <span class="hljs-number">741822</span>a.<span class="hljs-number">.10630</span>f2
Fast-forward
 chapter<span class="hljs-number">-3.</span>txt | <span class="hljs-number">1</span> +
 <span class="hljs-number">1</span> file changed, <span class="hljs-number">1</span> insertion(+)
 create mode <span class="hljs-number">100644</span> chapter<span class="hljs-number">-3.</span>txt
</code></pre><p>The <code>git pull</code> command is actually a shorthand for running two commands: <code>git fetch</code> followed by a <code>git merge</code>.</p>
<p>Since <code>git fetch</code> doesn't apply any changes locally, it can be useful to use <code>git fetch</code> to see if our branches are up to date with the remote (maybe we don't want to merge in the changes yet), or to pull down new branches that exist on the remote and not on our local machine. </p>
<p>Fetching a <em>new</em> branch from a remote will go ahead and download that branch as well to your local machine—since it's a new branch it won't conflict with anything in your local setup.</p>
<p>We could have just done a <code>git pull</code> initially instead of first doing a <code>git fetch</code>, but I wanted to explain <code>git fetch</code> as it is useful in its own right.</p>
<p>After running <code>git pull</code>, if we run <code>git status</code> once again we'll see that everything is up to date.</p>
<p>And with that, we've pulled in changes from our remote and got our local up to date!</p>
<h2 id="heading-how-to-fix-merge-conflicts-in-git">How to fix merge conflicts in Git</h2>
<p>The final topic we'll cover is how to deal with conflicts.</p>
<p>So far, Git has just magically handled all of the file updating, and most of the time Git can just handle it. But, there are times when Git doesn't know how to combine changes together, and that creates a <strong>conflict.</strong></p>
<p>A conflict occurs when merging two changes that have changed the same line in a file. If two commits have changed the same line in a file, Git doesn't know which commit's changes to use, and it will require you to make the choice.</p>
<p>To setup this scenario, I've created another branch on Github called <code>chapter-3-collaboration</code>. Let's imagine that a teammate has already started working on this branch and they've asked you to collaborate with them in finishing out Chapter 3.</p>
<p>Since this is a new branch that we don't have locally, we can use <code>git fetch</code> to retrieve the new branch information from the remote, and then switch to that branch using <code>git checkout</code>:</p>
<pre><code>(main)$ git fetch
From github.com:johnmosesman/practical-git-tutorial
 * [<span class="hljs-keyword">new</span> branch]      chapter<span class="hljs-number">-3</span>-collaboration -&gt; origin/chapter<span class="hljs-number">-3</span>-collaboration

(main)$ git checkout chapter<span class="hljs-number">-3</span>-collaboration
Branch <span class="hljs-string">'chapter-3-collaboration'</span> set up to track remote branch <span class="hljs-string">'chapter-3-collaboration'</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'origin'</span>.
Switched to a <span class="hljs-keyword">new</span> branch <span class="hljs-string">'chapter-3-collaboration'</span>
(chapter<span class="hljs-number">-3</span>-collaboration)$
</code></pre><p>We've now pulled down the new branch to our local repository and switched to it. This is the contents of <code>chapter-3.txt</code> on this new branch currently:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ cat chapter<span class="hljs-number">-3.</span>txt
Chapter <span class="hljs-number">3</span> - The End?

This is a sentence.
</code></pre><p>It's a title and one sentence. Let's change the title to something new like <em>"Chapter 3 - The End Is Only The Beginning."</em></p>
<p>The contents of <code>chapter-3.txt</code> now look like this:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ cat chapter<span class="hljs-number">-3.</span>txt
Chapter <span class="hljs-number">3</span> - The End Is Only The Beginning

This is a sentence.
</code></pre><p>After committing that change, if we try to push it up we get this message:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ git push origin chapter<span class="hljs-number">-3</span>-collaboration
To github.com:johnmosesman/practical-git-tutorial.git
 ! [rejected]        chapter<span class="hljs-number">-3</span>-collaboration -&gt; chapter<span class="hljs-number">-3</span>-collaboration (non-fast-forward)
<span class="hljs-attr">error</span>: failed to push some refs to <span class="hljs-string">'git@github.com:johnmosesman/practical-git-tutorial.git'</span>
<span class="hljs-attr">hint</span>: Updates were rejected because the tip <span class="hljs-keyword">of</span> your current branch is behind
<span class="hljs-attr">hint</span>: its remote counterpart. Integrate the remote changes (e.g.
hint: <span class="hljs-string">'git pull ...'</span>) before pushing again.
hint: See the <span class="hljs-string">'Note about fast-forwards'</span> <span class="hljs-keyword">in</span> <span class="hljs-string">'git push --help'</span> <span class="hljs-keyword">for</span> details.
</code></pre><p>Our teammate has already made some commits before we did, and pushed it to the remote branch. Our local branch is now out of date with the remote, and GitHub is denying our push until we merge in the changes from our teammate:</p>
<pre><code>... the tip <span class="hljs-keyword">of</span> your current branch is behind its remote counterpart. Integrate the remote changes ... before pushing again.
</code></pre><p>It also gives us a hint about how to do that: <code>git pull</code>.</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ git pull origin chapter<span class="hljs-number">-3</span>-collaboration
From github.com:johnmosesman/practical-git-tutorial
 * branch            chapter<span class="hljs-number">-3</span>-collaboration -&gt; FETCH_HEAD
Auto-merging chapter<span class="hljs-number">-3.</span>txt
CONFLICT (content): Merge conflict <span class="hljs-keyword">in</span> chapter<span class="hljs-number">-3.</span>txt
Automatic merge failed; fix conflicts and then commit the result.
</code></pre><p>After pulling—and as we might have expected given the topic we're currently discussing—we have a merge conflict.</p>
<p>Git tried to automatically merge our teammate's changes into ours, but there was a place in the file that it couldn't automatically merge—we both changed the same line.</p>
<p>Git stopped "mid-merge" and is telling us we need to fix the merge conflicts before it can finish the merge. Let's look at our <code>git status</code> currently:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ git status
On branch chapter<span class="hljs-number">-3</span>-collaboration
Your branch and <span class="hljs-string">'origin/chapter-3-collaboration'</span> have diverged,
and have <span class="hljs-number">1</span> and <span class="hljs-number">1</span> different commits each, respectively.
  (use <span class="hljs-string">"git pull"</span> to merge the remote branch into yours)

You have unmerged paths.
  (fix conflicts and run <span class="hljs-string">"git commit"</span>)
  (use <span class="hljs-string">"git merge --abort"</span> to abort the merge)

Unmerged paths:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to mark resolution)
        both modified:   chapter<span class="hljs-number">-3.</span>txt

no changes added to commit (use <span class="hljs-string">"git add"</span> and/or <span class="hljs-string">"git commit -a"</span>)
</code></pre><p>Git tells us our branch and the remote branch have 1 commit different from each other. It also tells us that we have some "unmerged paths"—that we're currently mid-merge and we need to fix the conflicts.</p>
<p>It shows us <code>chapter-3.txt</code> is currently modified, so let's look at the contents of <code>chapter-3.txt</code>:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ cat chapter<span class="hljs-number">-3.</span>txt
&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
Chapter <span class="hljs-number">3</span> - The End Is Only The Beginning
=======
Chapter <span class="hljs-number">3</span> - The End But Not The Ending
&gt;&gt;&gt;&gt;&gt;&gt;&gt; <span class="hljs-number">2</span>f6874f650a6a9d2b7ccefa7c9618deb1d45541e

This is a sentence.
</code></pre><p>Git has added some markers to the file to show us where the conflict happened. Both we and our teammate changed the title sentence, so it's surrounded by Git's markers of a conflict: <code>&lt;&lt;&lt;</code> and <code>&gt;&gt;&gt;</code> arrows separated by a line of <code>===</code>.</p>
<p>The top line, signified by <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</code> and followed by <em>"Chapter 3 - The End Is Only The Beginning"</em>, is the change that we just made. Git is telling us that this line is where our current <code>HEAD</code> is at—i.e., this is the change at our current commit.</p>
<p>The line below it, <em>"Chapter 3 - The End But Not The Ending"</em> followed by <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; 2f6874f650a6a9d2b7ccefa7c9618deb1d45541e</code>, is the line and commit from our teammate.</p>
<p>Basically, Git is telling us, "Which one of these lines (or some combination of these lines) do you want to keep?"</p>
<p>Notice that the line at the bottom file isn't wrapped up in the conflicts—it wasn't changed by both commits.</p>
<p>We need to resolve the conflict by deleting one of the lines or combining the two lines into one (and remember to remove all of the extra markers that Git put in there as well).</p>
<p>I'm going to take a combination of these lines, so the final file looks like this:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ cat chapter<span class="hljs-number">-3.</span>txt
Chapter <span class="hljs-number">3</span> - The End Is Not The Ending--But Only The Beginning

This is a sentence.
</code></pre><p>To finish the merge, we just need to commit our conflict resolution:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ git add .
(chapter<span class="hljs-number">-3</span>-collaboration)$ git commit -m <span class="hljs-string">"Merge new title from teammate"</span>
[chapter<span class="hljs-number">-3</span>-collaboration bd621aa] Merge <span class="hljs-keyword">new</span> title <span class="hljs-keyword">from</span> teammate

(chapter<span class="hljs-number">-3</span>-collaboration)$ git status
On branch chapter<span class="hljs-number">-3</span>-collaboration
Your branch is ahead <span class="hljs-keyword">of</span> <span class="hljs-string">'origin/chapter-3-collaboration'</span> by <span class="hljs-number">2</span> commits.
  (use <span class="hljs-string">"git push"</span> to publish your local commits)

nothing to commit, working tree clean
</code></pre><p>The result of <code>git status</code> tells us that our local branch is <code>is ahead of 'origin/chapter-3-collaboration' by 2 commits.</code>.</p>
<p>Looking at the <code>git log</code> confirms this:</p>
<pre><code>commit bd621aa0e491a291af409283f5fd1f68407b94e0 (HEAD -&gt; chapter<span class="hljs-number">-3</span>-collaboration)
<span class="hljs-attr">Merge</span>: <span class="hljs-number">74</span>ed9b0 <span class="hljs-number">2</span>f6874f
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Thu Mar <span class="hljs-number">25</span> <span class="hljs-number">09</span>:<span class="hljs-number">20</span>:<span class="hljs-number">42</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Merge <span class="hljs-keyword">new</span> title <span class="hljs-keyword">from</span> teammate

commit <span class="hljs-number">74</span>ed9b0d0d9154c912e1f194f04dbd6abea602e6
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Thu Mar <span class="hljs-number">25</span> <span class="hljs-number">09</span>:<span class="hljs-number">02</span>:<span class="hljs-number">03</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    New title

commit <span class="hljs-number">2</span>f6874f650a6a9d2b7ccefa7c9618deb1d45541e (origin/chapter<span class="hljs-number">-3</span>-collaboration)
<span class="hljs-attr">Author</span>: John Mosesman &lt;johnmosesman@gmail.com&gt;
<span class="hljs-built_in">Date</span>:   Thu Mar <span class="hljs-number">25</span> <span class="hljs-number">08</span>:<span class="hljs-number">58</span>:<span class="hljs-number">58</span> <span class="hljs-number">2021</span> <span class="hljs-number">-0500</span>

    Update title

...
</code></pre><p>The resulting commit history has both of the commits on the branch and our merge commit at the top.</p>
<p>From here, we just need to push up our changes to the remote:</p>
<pre><code>(chapter<span class="hljs-number">-3</span>-collaboration)$ git push origin chapter<span class="hljs-number">-3</span>-collaboration
Enumerating objects: <span class="hljs-number">10</span>, done.
Counting objects: <span class="hljs-number">100</span>% (<span class="hljs-number">10</span>/<span class="hljs-number">10</span>), done.
Delta compression using up to <span class="hljs-number">16</span> threads
Compressing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">6</span>/<span class="hljs-number">6</span>), done.
Writing objects: <span class="hljs-number">100</span>% (<span class="hljs-number">6</span>/<span class="hljs-number">6</span>), <span class="hljs-number">647</span> bytes | <span class="hljs-number">647.00</span> KiB/s, done.
Total <span class="hljs-number">6</span> (delta <span class="hljs-number">2</span>), reused <span class="hljs-number">0</span> (delta <span class="hljs-number">0</span>)
<span class="hljs-attr">remote</span>: Resolving deltas: <span class="hljs-number">100</span>% (<span class="hljs-number">2</span>/<span class="hljs-number">2</span>), completed <span class="hljs-keyword">with</span> <span class="hljs-number">1</span> local object.
To github.com:johnmosesman/practical-git-tutorial.git
   <span class="hljs-number">2</span>f6874f..bd621aa  chapter<span class="hljs-number">-3</span>-collaboration -&gt; chapter<span class="hljs-number">-3</span>-collaboration
</code></pre><p>Now that we've changed the remote branch, our teammate would need to do a <code>git pull</code> to merge in our new merged changes. </p>
<p>And, ideally we would tell our teammate that we pushed up a new change so they could pull it down before they continue editing—reducing the likelihood <em>they'll</em> have to fix a merge conflict in the future, too.</p>
<h3 id="heading-branches-off-of-branches">Branches off of branches</h3>
<p>We could have also created our own branch off of the <code>chapter-3-collaboration</code> branch. This would let us work without having to worry about merge conflicts until the very end. </p>
<p>Once we had finished our work in our own separate branch, we could then merge <em>our</em> feature branch into our <em>teammate's</em> feature branch—and then into <code>main</code>.</p>
<blockquote>
<p><code>chapter-3-collaboration-john</code> -&gt; <code>chapter-3-collaboration</code> -&gt; <code>main</code></p>
</blockquote>
<p>As you can see the branch structure can get quite complicated as more and more branches branch off of each other and become ahead of and behind each other.</p>
<p>Because of this, it's generally a good idea to keep branches <strong>small and isolated</strong> and try to <strong>merge them quickly and often.</strong></p>
<p>This can help avoid a lot of painful merge conflicts.</p>
<h2 id="heading-review-how-to-start-a-new-feature-workflow">Review: how to start a new feature workflow</h2>
<p>I'll end with a quick review of how to approach starting a new task and the commands and flows to do it.</p>
<p>Say you've been given your first ticket at a new job: a small bug to squash in your team's product.</p>
<p>The first thing you'd need to do is pull down the repo using <code>git clone &lt;URL&gt;</code>.</p>
<p>Next, you'd want to make a feature branch off of <code>main</code> using <code>git checkout -b &lt;BRANCH_NAME&gt;</code>. After that, you'd fix the bug and commit the change(s) using <code>git add</code> and <code>git commit</code>.</p>
<p>Maybe solving this problem takes multiple commits—or maybe you make a few commits in an attempt to solve it before you finally arrive at the solution. That's ok too.</p>
<p>After committing, you push your new branch to the <code>origin</code> (<code>git push origin &lt;BRANCH_NAME&gt;</code>) and create a pull request. After a code review your branch is merged in (yay!).</p>
<p>You've now completed your feature, and it's time to switch back to <code>main</code> (using <code>git checkout main</code>), use <code>git pull</code> to get your latest changes plus any other changes other people have made, and start off again with a new branch.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As mentioned in the beginning, there are many ways to approach working with Git and Git workflows. </p>
<p>There's also a lot of underlying Git "magic" (that is, code being run that you don't understand yet), but you will learn and pick up more of this with time.</p>
<p>I spent the first many years of my career just using memorized commands and workflows. It worked. As I ran into problems or collaborated with teammates I learned more and eventually my skill with Git expanded.</p>
<p>In the beginning, don't make it any harder than it has to be! You will learn over time.</p>
<p>If you liked this article, I write about technical topics like this as well as non-technical topics <a target="_blank" href="https://johnmosesman.com/">on my site.</a></p>
<p>I also write similar things on Twitter: <a target="_blank" href="https://twitter.com/johnmosesman">@johnmosesman</a>.</p>
<p>Either way, feel free to send me a message.</p>
<p>Thanks for reading!</p>
<p>John</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Develop a Reusable eCommerce Platform ]]>
                </title>
                <description>
                    <![CDATA[ By Ramón Morcillo This is a story about my team’s hard work developing not a single eCommerce platform, but a reusable one for different owners. We kept the same codebase, look, and feel, and made it highly customizable.  I will conclude with what we... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/develop-a-reusable-ecommerce-platform/</link>
                <guid isPermaLink="false">66d460c54bc8f441cb6df81f</guid>
                
                    <category>
                        <![CDATA[ architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 30 Dec 2020 19:48:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/12/plants.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ramón Morcillo</p>
<p>This is a story about my team’s hard work developing not a single eCommerce platform, but a reusable one for different owners. We kept the same codebase, look, and feel, and made it highly customizable. </p>
<p>I will conclude with what we learned from the process. I think our takeaways will be a useful learning resource for other software developers out there (and for ourselves in future projects, as well).</p>
<p>I will try to focus on the relevant parts as much as possible to make it easier to understand. Having said this, a bit of background is needed to go through this article.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li>Context of the project</li>
<li>The first MVP</li>
<li>Implementing GraphQL</li>
<li>Architecture and Tech Stack</li>
<li>The second MVP</li>
<li>Conclusion and lessons learned</li>
<li>Final thoughts</li>
</ul>
<h2 id="heading-context-of-the-project">Context of the project</h2>
<p>The client we were developing the platform for was an eLearning company which was composed of 3 main sub-companies.</p>
<p>For the past few years, the sub-companies had been operating mostly independently. But now they were trying to create a standardized way of doing things, so they could grow together in the best way.</p>
<p>The project was an ambitious one. Creating an ecommerce platform that would work for all the sub-companies wasn’t easy to design or to implement. There were a large number of unsolved questions they had, which made it very hard to estimate.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/doubts-2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-the-first-mvp">The first MVP</h2>
<p>To tackle this difficult challenge, we started from the bottom with one of the 3 sub-companies – let’s call it sub-company H. In fact, it wasn’t one of the main sub-companies, it was a sub-company from a sub-company. </p>
<p>To explain it better, if we name the 3 main sub-companies L, N, and P, then H was a sub-company of N.</p>
<p>Being a sub-sub-company didn’t mean the platform would be simpler to develop. It was quite the opposite, actually, given all the features proposed for the MVP.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/main_company_structure-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Main company structure</em></p>
<p>While the main goal was for a user to be able to purchase a product (seems quite obvious), there were too many dependencies with other services to accomplish this seemingly simple MVP.</p>
<p>Part of the product and order information came from another team’s domain, the Integrations team (I will call it team <em>In</em>). They communicated with <a target="_blank" href="https://www.swell.is/">Swell</a> and Klopotek, an ecommerce system where we stored the product's information along with the order’s status.</p>
<p>The discounts were also provided by team <em>In’s</em>, to which we had to subscribe and then calculate the final product price according to the user info and privileges before displaying it.</p>
<p>To make product content like images or descriptions accessible and customizable for the client we retrieved it through <a target="_blank" href="https://www.contentful.com/">Contentful</a>, a content platform where clients were able to manage it in an easy way.</p>
<p>We managed the payment with <a target="_blank" href="https://stripe.com/">Stripe</a>, a payments service, and then we communicated with team <em>In</em> to update the order status on Swell.</p>
<p>The service available for the user to authenticate should be agnostic to the owner and reusable on all sub-companies. It had to be provided by another team, yet in the end, we actually developed it ourselves.</p>
<p>And to put the icing on the cake, we also had to implement the user tracking with <a target="_blank" href="https://segment.com/">Segment</a>, a popular service to collect user events from web and mobile apps.</p>
<p>Here is a simple diagram of what I have been describing which might make it easier to understand. I have grouped the microservices architecture in just <em>Backend</em> and <em>Frontend</em> to keep it simple.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/mvp_architecture_overview-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>MVP Architecture overview</em></p>
<h2 id="heading-why-we-chose-graphql">Why We Chose GraphQL</h2>
<p>To accomplish our goals for the project, we had to <em>provide the frontend with a unique source of truth</em> of the product’s core information from the backend. </p>
<p>Therefore the only thing that we aimed to have different from one store’s frontend to another would be the designs and the content from Contentful. </p>
<p>Regarding these designs and their implementations on React, we planned to use a shared-components-library.</p>
<p>Therefore, what is GraphQL doing here and why did we decide to go for it? </p>
<p>Well, in case you don’t know how GraphQL works, essentially it lets you define a Schema with all the properties and queries that could be made to your product. Then it lets you serve it to the frontend to let it decide what to request without the backend having to create an endpoint for each of those requests (like in REST services). </p>
<p>To learn more about it, check out this tutorial <a target="_blank" href="https://www.ramonmorcillo.com/getting-started-with-graphql-and-nodejs/">I wrote to explain it</a>. It teaches you how to use it with Node.js. Also, <a target="_blank" href="https://graphql.org/learn/">their docs</a> are worth checking out.</p>
<p>This meant that each of the shops would request the data they needed from the product just by looking at the Schema, the source of truth. </p>
<p>Thanks to this fact we would not have to implement different sources of data  in the backend for each shop. This gave the frontend the power and responsibility (the first involves the second 🕷) to request the product data needed to display at each interface.</p>
<blockquote>
<p>With great power comes great responsibility.
— Stan Lee</p>
</blockquote>
<p>Just to be clear, if we had decided to go with REST we would have needed to create different endpoints for each of the shops. Or we would have had to make the frontend retrieve all the product data in each shop and then decide which properties to display. This means it would've had to store unnecessary data in the frontend that would only add noise. </p>
<p>Or even worse, we would have had all the shops’ backend services deployed for each one of the frontend shops. This would've used unnecessary resources and increased the cost considerably. </p>
<p>Here is why we took this initial approach. The worst part, in my opinion, would've been the waste of time from maintaining and hardly refactoring all the mess that we would have created.</p>
<p>Furthermore, by making a single request on-demand, the payload was lighter, and therefore, the performance over the network was improved.</p>
<p>Anyway, as with every problem, there were other approaches we could've taken on the way to developing this project and its architecture. But at that moment this one seemed to us the best one.</p>
<h2 id="heading-architecture-and-tech-stack">Architecture and Tech Stack</h2>
<p>The microservices architecture mainly consisted of Node.js services hosted on Azure K8s clusters. Depending on their needs and the data they worked with, they did or didn't have a MongoDB, PostgreSQL, or Redis database associated.</p>
<p>The asynchronous communication between them was handled mainly with <a target="_blank" href="https://azure.microsoft.com/en-us/services/service-bus/">Azure Service Bus</a> topics and subscriptions through a publish/subscribe messaging communication model. </p>
<p>The main difference with common messaging queues is that you can have more than one receiver, so you do not have multiple queues to receive messages in more than one service.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/azure_service_bus_messaging_queues-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Azure Service Bus messaging Queues. <a target="_blank" href="https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview#queues">Source</a></em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/azure_service_bus_messaging_topics-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Azure Service Bus messaging Topics. <a target="_blank" href="https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview#topics">Source</a></em></p>
<p>On the frontend part, the sites were developed with React. Sometimes we used <a target="_blank" href="https://github.com/vercel/next.js/">Next</a>, and other ones we built from scratch with <a target="_blank" href="https://github.com/facebook/create-react-app">Create React App</a>, depending on the complexity and the requirements of each. </p>
<p>We moved from Redux, used in previous projects, to the official <a target="_blank" href="https://reactjs.org/docs/context.html">Context API</a> to manage most of the state.</p>
<p>Here are the main services and their functionalities for the first MVP architecture: </p>
<ul>
<li><strong>shop-web-app:</strong> The client shop application.</li>
<li><strong>gateway-api-service:</strong> Proxy service to receive requests from the client and redirect them to the corresponding services.</li>
<li><strong>cms-api-service:</strong> Service to retrieve and serve the content from Contentful</li>
<li><strong>catalog-api-service:</strong> Service that subscribes to team In messages and persists the product core data to serve it later through GraphQL.</li>
<li><strong>orders-api-service.</strong> Service that handles all the payment business logic</li>
<li><strong>auth-api-service:</strong> Provisional service to implement the user authentication to be able to buy products.</li>
<li><strong>auth-web-app:</strong> The client for the auth service.</li>
<li><strong>integrations-ecommerce-api-service:</strong> service from the integrations domain that handles the payments. Although this service was not in our domain we developed it together to increase the delivery speed and free them from extra work.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/first_mvp_arquitecture-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>First MVP architecture</em></p>
<p>To deploy and update the resources needed on Azure we used <a target="_blank" href="https://www.terraform.io/">Terraform</a>, which let us define infrastructure as code and manage their life cycles on the K8s clusters. We also worked with Azure DevOps as our CI &amp; CD system.</p>
<p>On the services, we used <a target="_blank" href="https://github.com/guidesmiths/systemic">Systemic</a>, a Node.js framework for minimal dependency injection that lets you create components and their dependencies in a system. Each component handles a separate object from the domain such as the routing, controller, services, database, and so on in an agnostic way from the others.</p>
<p><a target="_blank" href="https://www.apollographql.com/">Apollo</a> was our choice to implement GraphQL. It provided us with a data graph layer to easily connect both frontend and backend. </p>
<p>Again, to learn more about it check out <a target="_blank" href="https://www.apollographql.com/docs/">their docs</a> or <a target="_blank" href="https://www.ramonmorcillo.com/getting-started-with-graphql-and-nodejs/">this tutorial.</a> </p>
<p>Finally, we hosted the code on <a target="_blank" href="https://github.com/">GitHub</a> to make use of features like Pull Requests to review our code properly before implementing it.</p>
<h2 id="heading-the-second-mvp">The second MVP</h2>
<p>An MVP (Minimum Viable Product) is the first prototype you create and deliver in a project. This means that there is usually just one, and when you create it you start implementing new features on it. </p>
<p>So, why did we focus on a second MVP for the same project? Well, when we reached a “stable” version of the first one, the client realized that we needed to start with the main sub-company stores. They decided to stop the sub-sub-company H store development to focus on the development of the new ones. </p>
<p>This was mainly because to some services ended their support for the sub-companies in the coming months, meaning that their stores had to be developed first.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/how_we_felt_with_second_mvp-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Graphical representation of how we felt with the second MVP</em></p>
<p>Although we tried to make a proper estimation for the first MVP, we surpassed its deadline since some unplanned issues appeared along the way. Thus, when we were told that the new deadline would be even sooner, we decided to take a different approach to reach it on time. </p>
<p>We decided to develop more than one store at the same time, which was a double-edged sword approach. </p>
<p>On one hand, we would see on the go how well the reusability aspect of our platform worked while refactoring it. We would also end up with more than one store in the end. </p>
<p>On the other hand, we would have to set up and maintain the environments and resources of multiple shops. Plus we would have to implement their designs which would slow us down, meaning we might not reach the deadline on time, again.</p>
<p>We saw this MVP as an opportunity to start over and improve our codebase. So we added TypesScript and Styled-Components to our React application. </p>
<p>I have to admit that I was very happy when we made these choices because I had been working with that stack on <a target="_blank" href="https://github.com/reymon359?tab=repositories&amp;q=&amp;type=source&amp;language=typescript">my own projects</a>. So now I was able to learn more and get even better at it.</p>
<p>Fortunateluy, we were able to reuse most of the code from the previous MVP for the React apps and the backend services. But not everything was a bed of roses. </p>
<p>Not all of us were used to working with this new stack and it slowed us down at the beginning. Furthermore, with the same stack, we started developing a React components library for all the platforms, which, even though it was planned for the first MVP, never saw the light.</p>
<p>By that time, the team in charge of the user authentication service started working on it so we stopped its development and just implemented it on the site. </p>
<p>In addition, we started the development of a products search service (<strong>search-api-service</strong>) with <a target="_blank" href="https://azure.microsoft.com/en-us/services/search/">Azure Cognitive Search</a>.</p>
<p>After all the changes mentioned above the architecture evolved this way.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/second_mvp_arquitecture.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Second MVP architecture</em></p>
<h2 id="heading-conclusion-and-lessons-learned">Conclusion and lessons learned</h2>
<p>As I am writing this, the platform isn’t finished yet. But it has been a great challenge to get where we are. </p>
<p>We have learned some valuable lessons that can be useful to others, not just about the stack and architecture described above but about the way we worked as a team.</p>
<h3 id="heading-innovate-the-stack">Innovate the stack</h3>
<p>Working with new technologies can be risky and less comfortable than sticking with old and well-known ones. But innovation and adaptability is the right way to go so you don't get left behind in Software Development. </p>
<p>One of the most important points when you upgrade your stack or adopt a new one, apart from checking the proper way to do so following standards, is <em>being sure the team is comfortable working with it,</em>. Not just at the beginning, either, but during the whole process to make the transition easier.</p>
<h3 id="heading-dont-underestimate-promise-less-deliver-more">Don’t underestimate, promise less, deliver more</h3>
<p>We happily estimated the first MVP and agreed to deliver a great number of features. We ended up needing more time because of all the issues that appeared on the way and _had to learn to say “no” <em>sometimes.</em> </p>
<p>On the second MVP, we didn’t estimate that far ahead in time and didn’t commit ourselves to features we weren’t sure we could deliver within the time expected. </p>
<p>Because of this, we were able to work less stressed, have a better mood, deliver better code, and improve the client's feelings about the project since they weren’t disappointed with the progress.</p>
<h3 id="heading-teamwork-inside-the-team">Teamwork inside the team.</h3>
<p>We realized that the best way to progress and develop was to feel comfortable – not just with the technologies but, most importantly, our teammates. Some of the measures that improved our relationship and teamwork were:</p>
<h4 id="heading-team-democracy">Team democracy.</h4>
<p>No matter the work we were doing at the moment, <em>all of us had the same voice and our opinion counted the same</em> when making a choice. This was key when we discussed the adoption of the new stack and the practices we would follow.</p>
<h4 id="heading-reviewing-code">Reviewing code.</h4>
<p>Feedback is one of the best ways to improve not only the code itself but the way you write it too. That's why we decided to work with GitHub Pull Requests to implement most of the features. </p>
<p><em>Working with them not only improved our code base but also made us aware of how the features were being implemented in other areas, avoiding catchup meetings and helping us keep track of the full project scope</em>. </p>
<p>We refined this system little by little with features like a <a target="_blank" href="https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/about-required-reviews-for-pull-requests">minimum number of reviewers to merge them</a> or <a target="_blank" href="https://github.com/integrations/slack">subscribing to them through slack.</a></p>
<h4 id="heading-helping-and-asking-for-help">Helping and asking for help.</h4>
<p>In my opinion, this one is a must. <em>The team must lose the fear of asking for help if they get stuck. At the same time, they must be willing to help others when they ask for it.</em> </p>
<p>I am happy to say that we were able to reach this balance and our work improved in many ways. The next point, pairing, was key in losing the fear of asking for help and getting to know each other better.</p>
<h4 id="heading-pairing-as-much-as-possible">Pairing as much as possible.</h4>
<p>At this point in software development, the advantages of doing pair programming are quite well known. We paired not just to deliver the features in a faster and better way of doing things, but to learn from each other's way of coding. </p>
<p>Each week, we decided the pairing tasks and teammates to implement them. But if someone needed or wanted to pair, we just asked for it and moments after a teammate offered to help.</p>
<h4 id="heading-paying-attention-to-feedback">Paying attention to feedback.</h4>
<p>The sprint retrospectives were the perfect moment to review all the things that went well, those that went wrong, to propose changes, and to look forward to improvement. Therefore the more we shared our opinions the more issues we could approach and solve.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/teamwork_makes_the_dream_work.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-teamwork-with-other-partners">Teamwork with other partners.</h4>
<p>We were dependent on other teams' work – so having a good relationship with them was also an important point in our development process. </p>
<p><em>Communication was the key point: the more we communicated the more we improved,</em>. And thanks to this, our goal was to be one whole team. Here are some actions we followed in order to enhance this communication:</p>
<ul>
<li><strong>Have a private place just for us.</strong> We created a separate channel to talk about the progress and solve any questions or doubts as soon as possible without extra meetings.</li>
<li><strong>Quick meetings.</strong> A meeting once a week worked great to check the progress on the main issues. But we did not always wait for this one meeting, and had a quick call whenever an issue needed to be discussed.</li>
<li><strong>Stay updated on the overall progress.</strong> We had a teammate from our team attending their daily standups and one of them at ours who updated the rest of the team if needed.</li>
</ul>
<p>Here is some actual footage of us and the Integrations Team:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/source--1-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-make-the-client-feel-like-part-of-the-team">Make the client feel like part of the team.</h4>
<p>At the beginning of the first MVP, there were too many clues and too little communication to clarify them so we were blocked sometimes or had to set up time-wasting meetings for these issues. </p>
<p>The core of the problem, like most problems in life, was a lack of communication. So we solved it by increasing our communication, asking questions directly to the client, inviting them to retrospectives, daily standups, and other meetings even when they were not required.</p>
<p>This helped keep the client updated as much as possible. In the end, the more we communicated the more we made them feel part of the team, and the better we worked together.</p>
<h2 id="heading-final-thoughts">Final thoughts</h2>
<p>I want to first thank my teammates. It has been a pleasure to work with them, starting each day eager to have fun together developing the project.</p>
<p>On the same level, thank you to the teammates from other teams who always gave a helping hand when requested.</p>
<p>I'm also thankful for the opportunity to participate in the full end-to-end implementation of the project from which I learned so much. I solved issues on Front, Back, and DevOps such as setting up environments, pipelines, messaging between services, persisting and retrieving data, serving it to the frontend, and implementing the interfaces to display it.</p>
<p>Finally, I am thankful for having the chance to work and get better at technologies that I was using on side-projects like GraphQL or TypeScript.</p>
<p>I hope you enjoyed this article. You can read <a target="_blank" href="https://ramonmorcillo.com/developing-a-reusable-ecommerce-platform/">it too on my site</a> along with others! If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on any of the social networks from <a target="_blank" href="https://ramonmorcillo.com/">my site</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How a Single Priority Can Make Your Tech Team More Productive ]]>
                </title>
                <description>
                    <![CDATA[ Stop giving your development team too many things to do first. Whether you’re leading a team of people or leading yourself, it’s important to take account of all the important things that need doing in your organization. And to realize that this does... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-a-single-priority-makes-your-tech-team-more-productive/</link>
                <guid isPermaLink="false">66bd8f2cffb0fc5947cc9125</guid>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Thu, 17 Dec 2020 17:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/12/task-selection.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Stop giving your development team too many things to do first.</p>
<p>Whether you’re leading a team of people or leading yourself, it’s important to take account of all the important things that need doing in your organization. And to realize that this does not mean that everything can be equally important.</p>
<p>Logically, everything can’t be. Tasks are typically interdependent, and there’s always one task on which another depends. Tasks can be time-sensitive. Certain tasks might block a logical path towards a goal.</p>
<p>It’s the duty of a leader to make hard calls and decide which tasks are most important out of everything that needs doing. This necessitates comparing one to another, which is much easier to do with a centralized to-do list.</p>
<p>Here’s how this one simple change to your perspective on to-do lists can help to build happier and more productive teams.</p>
<h2 id="heading-keep-a-central-prioritized-to-do-list">Keep a central prioritized to-do list</h2>
<p><img src="https://victoria.dev/blog/how-a-single-priority-makes-your-tech-team-more-productive/prioritize.png" alt="A cartoon of a stick figure swinging on a rope ro plant a post-it note" width="600" height="400" loading="lazy"></p>
<p>Avoid working in silos. A single centralized list can make it easier for you and your team members to see what’s being worked on. With all tasks out in the open, it’s easier for people to spot opportunities for helping each other out and where they can contribute.</p>
<p>Encouraging a culture of openness can help people feel more comfortable asking questions, asking for help, and proposing ideas and improvements. Tracking work in the open also means that no one is left wondering what status a task is currently in.</p>
<p>For team leaders, a single list makes it easier to compare and prioritize tasks. This benefits team members by providing a completely unambiguous and transparent accounting of what needs doing next. Whichever task is most important, for the whole organization, is on top.</p>
<h2 id="heading-priorities-with-autonomy">Priorities with autonomy</h2>
<p>A single priority doesn’t necessarily pigeonhole someone into doing a task they don’t feel cut out for. Each member of your team has different strengths, skill sets, and diverse ways of thinking. You can take full advantage of this by encouraging autonomy in task selection.</p>
<p><img src="https://victoria.dev/blog/how-a-single-priority-makes-your-tech-team-more-productive/task-selection.png" alt="A cartoon of a stick figure climbing a ladder to reach a post-it note" width="600" height="400" loading="lazy"></p>
<p>Have people choose whichever task is nearest to the top that they’d like to tackle. They might pick the highest priority task that’s in their wheelhouse, or experiment with a higher one that’s in a domain they’d like to improve their skills at.</p>
<p>Embrace opportunities for cross-training. If tasks high up on the list fall in a category that only one or a few people on your team are experts in, have your experts partner up with another team member who’s taking on the task. </p>
<p>By pooling your resources to cross-train across domains, you multiply the capabilities of each team member and your team as a result.</p>
<p>When a task is especially time-sensitive, have several team members swarm on it and distribute the work according to their interests or strengths.</p>
<h2 id="heading-make-yourself-redundant">Make yourself redundant</h2>
<p>Working off a single prioritized to-do list works best when your team members can take on tasks as independently as possible. This is especially important in remote teams where people work asynchronously.</p>
<p>If you’re a leader and find that your team members frequently ask you what they should do next, you could be making your team dependent on you. Ask yourself if you’re unnecessarily gatekeeping information that would let your team be more autonomous.</p>
<p>A team that overly depends on their leader is not an efficient one. Individual people, such as yourself, don’t scale. Don’t become a bottleneck to your team’s productivity. </p>
<p>A successful leader should be able to take several days off on short notice without productivity grinding to a halt.</p>
<p><img src="https://victoria.dev/blog/how-a-single-priority-makes-your-tech-team-more-productive/add-resources.png" alt="A cartoon of a stick figure carrying books to a wall of post-it notes" width="600" height="400" loading="lazy"></p>
<p>To support your team’s ability to work without you, make your team, product, and company goals <em>painfully</em> available. </p>
<p>Put them where people hang out – your team’s message board, chat channel, or document repository, for example. No one should be at a loss when asked what the team wants to achieve next, and why.</p>
<p>Make any applicable resources, style guides, product documents, or links to external documentation painfully available as well. </p>
<p>If your team makes a decision about how something should be done, write it down. Don’t rely on yours or anyone else’s meat brain to remember an important decision, nor make yourself the only resource for recalling it.</p>
<p>Make yourself redundant when it comes to day-to-day work. Doing so empowers your team members to do work without you, think through solutions on their own, and propose paths of action that you probably wouldn’t have thought of yourself.</p>
<h2 id="heading-build-happier-and-more-productive-teams">Build happier and more productive teams</h2>
<p>From first-hand experience as both a team member and leader, I’ve seen how encouraging a culture of openness, cross-training, and autonomy makes for happier team members and more productive teams. </p>
<p>A single prioritized to-do list, coupled with available documentation and resources, opens the gates to let your technical team be maximally productive.</p>
<p>By removing bottlenecks, you allow people to make more decisions on their own and take ownership of their work. That’s a technical team I’d be proud to lead.</p>
<p>If you enjoyed this post, I'd love to know. Join the thousands of people who learn along with me on <a target="_blank" href="https://victoria.dev/">victoria.dev</a>! Visit or <a target="_blank" href="https://victoria.dev/index.xml">subscribe via RSS</a> for more about building happy and productive technical teams.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Be a Team Player as a Software Engineer ]]>
                </title>
                <description>
                    <![CDATA[ By Moshe Siegel In my first software engineering role at an eCommerce brand, I often secretly worked on tasks outside of my core responsibilities. And many times I felt isolated from my teammates.  Therefore, when I was invited to participate in a pr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-be-a-team-player/</link>
                <guid isPermaLink="false">66d46044246e57ac83a2c7a2</guid>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 29 Jun 2020 23:50:26 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c99fd740569d1a4ca22e3.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Moshe Siegel</p>
<p>In my first software engineering role at an eCommerce brand, I often secretly worked on tasks outside of my core responsibilities. And many times I felt isolated from my teammates. </p>
<p>Therefore, when I was invited to participate in a project-based course to better my communication skills, I jumped at the opportunity. </p>
<p>For the program, I was assigned to a team with two other engineers and a team lead to build a full stack application using React, Python, and Flask. Now that the course is over, I thought I'd share the lessons I learned about how to be a better team player. </p>
<h2 id="heading-lesson-1-do-not-underestimate-a-projects-potential-difficulty-level">Lesson 1: Do not underestimate a project’s potential difficulty level</h2>
<p>Since the course was meant for entry-level engineers, I figured I would have a leg up as I already had some professional Node.js experience. Granted, our tech stack would be using a Python Flask backend, but I figured Python and Flask would not be too hard to pick up. </p>
<p>On the first day of our project, we were shown what we would be building. Wow, I suddenly felt very unprepared. Our project was significantly more challenging than I had expected.</p>
<p>My other two teammates seemed to pick up the material easily. At the end of our first week I was our team’s least contributing member. </p>
<p>I knew React quite well, so our front end was not too difficult for me. But our backend was using PostgresSQL and Python, neither of which I knew well. It quickly became clear that the tasks expected of us would be particularly challenging for someone with little Python experience.</p>
<h2 id="heading-lesson-2-request-feedback-on-work-in-progress">Lesson 2: Request feedback on work in progress</h2>
<p>Initially, I often found myself wasting time doing unnecessary work. For instance, one time I was creating an editable user profile form, not realizing that my teammate was in the middle of building a reusable Material UI dialog component that I could have used. </p>
<p>Another time I spent time reading a tutorial on how to get the identity of an authenticated user, not realizing that my teammate had already figured it out. </p>
<p>Realizing how much time I was spending doing unnecessary work, I started posting in our Slack message board what I was working on and requesting feedback. My teammates were quick to respond. By having my colleagues give input on my unfinished designs, I was able to avoid duplicating work.</p>
<h2 id="heading-lesson-3-when-pressed-for-time-prioritize-what-to-avoid-learning">Lesson 3: When pressed for time, prioritize what to avoid learning</h2>
<p>Given that I struggled to keep up with the workload, I needed to better prioritize my time. Whenever someone created a new feature, they would create a Git Pull Request (PR) to ask for the code to be reviewed. At first, I reviewed every PR and gave each of them my full attention. However, this soon proved impractical. </p>
<p>I remember spending lots of time reviewing the PR to add cookies and tokens for authentication. To do a proper review, I first read lots of background info on security issues such as cookies, local storage, and cross site scripting attacks. When I finished all that reading I read through the PR, only to find all the code made sense and there was nothing for me to comment on. </p>
<p>In hindsight, given how far behind I was with my own tasks, I should have ignored much of the cookie documentation and instead done just a rapid PR review to save time. </p>
<p>Gaining an in-depth knowledge of the inner workings of our cookie authentication was of little use to my overall productivity. In contrast, other PRs such as the one which set up React Context to pass state through our app directly affected nearly every feature that I worked on. </p>
<p>Prioritizing gaining a deep understanding of that PR would have been a far more valuable use of my time.</p>
<h2 id="heading-lesson-4-build-new-features-by-going-from-chunk-to-chunk">Lesson 4: Build new features by going from chunk to chunk</h2>
<p>To get more organized, I had to learn how to skim through technical documentation. I called a senior engineering friend of mine, Sean Ellison-Chen, and asked his process for tackling a new feature that requires a technology that is brand new to him. </p>
<p>He explained that he first tries to understand at most 70% of what is going on, and then immediately starts building the feature in chunks. Each chunk gets committed to git. </p>
<p>For example, let’s say he needs to set up web sockets, he might set up a basic skeleton structure for web sockets, commit it to git, then work on the next chunk of setting up the correct socket events and so on. </p>
<p>By working in chunks, he ensures a smooth progression from tackling the bare minimums to eventually having a fully functioning feature.</p>
<h2 id="heading-lesson-5-request-feedback-from-your-team-lead">Lesson 5: Request feedback from your team lead</h2>
<p>Midway through the program, I received feedback from our team lead, Shums Kassam. I was told to ask for help more, to skim through documentation, and to leverage my teammates. </p>
<p>I took the advice to heart and upped the amount of times I posted in our message board. I started having video calls with teammates to review features I was building. I skimmed faster through the technical documentation and avoided the less critical areas. By implementing these changes, my rate of contributions sped up.</p>
<h2 id="heading-lesson-6-avoid-doing-a-perfect-job-on-tasks-whose-requirements-might-change">Lesson 6: Avoid doing a perfect job on tasks whose requirements might change</h2>
<p>By sheer luck, I learned the importance of procrastinating on tasks whose requirements might change. </p>
<p>One of my first tasks was building a front-end form that lets users change their profile info. When I submitted my code for review, I was told the form’s appearance needed to be fixed as some of the input lengths did not match. </p>
<p>Normally, I would have spent the 45 minutes to fix it right then and there. But I was far behind in my contributions, so instead I just commented a “todo” about matching the input lengths and merged my code. </p>
<p>A week later, a teammate pointed out it would be a better user experience to combine the separate ‘street’, ‘city’, ‘state’, and ‘country’ inputs into a single ‘address’ input. When he simplified the inputs, my commented out “todo” was no longer applicable. </p>
<p>By procrastinating with working on the form, I had saved myself from doing unnecessary work.</p>
<h2 id="heading-lesson-7-be-comfortable-submitting-non-refactored-code">Lesson 7: Be comfortable submitting non-refactored code</h2>
<p>Near the end of our project, our team was rushing to finish all our features prior to a fixed date when we would present our project to an audience. We planned to have all features submitted well in advance to give us enough time to practice and rehearse. </p>
<p>But I ended up submitting my final feature with barely an hour to our demo and we had to rush to add it in. Though our presentation went well, I was troubled that I submitted the feature so late as it severely reduced our team’s ability to rehearse our demo in advance. </p>
<p>In hindsight I realize that instead of submitting optimized and clean code, I could have saved at least two hours of time by simply adding comments about refactoring later.</p>
<p>Over the past few months, I learned many lessons about how to be a better team player. Most importantly, I learned that teamwork is a skill that can be improved just like any other.</p>
<p>The program I participated in was run by <a target="_blank" href="https://hatchways.io/">Hatchways</a>, a company that helps software engineers get their first jobs. At the time of this writing they service engineers and companies in North America. If you're an employer looking to hire interns or entry-level engineers see <a target="_blank" href="https://hatchways.io/employers">Hatchways - Employers</a>. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Value of Enablers and Gatekeepers on Development Teams ]]>
                </title>
                <description>
                    <![CDATA[ By Ovidiu Bute Teams should set and uphold a set of values. These come in different shapes and forms. Whether it’s being honest, transparent, responsible, or blameless. The list just goes on.  Values are only important if they’re connected to behavio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/enablers-and-gatekeepers/</link>
                <guid isPermaLink="false">66d4608a3a8352b6c5a2aacb</guid>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 20 Apr 2020 13:20:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9b8f740569d1a4ca2c97.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ovidiu Bute</p>
<p>Teams should set and uphold a set of <strong>values</strong>. These come in different shapes and forms. Whether it’s being honest, transparent, responsible, or blameless. The list just goes on. </p>
<p>Values are only important if they’re connected to behaviors, that is how you typically act regardless of the situation. Nobody behaves erratically over an extended period of time. After enough self-reflection patterns emerge, and those patterns can be associated with values. I’d like to focus on just two of them in this article.</p>
<h2 id="heading-the-enablers">The Enablers</h2>
<p>Throughout my software engineering career I kept hearing the word <strong>enablement</strong> thrown out a lot. Now, first of all, enabling someone to do something can have both positive and negative connotations. I think it’s only in this industry that it’s acceptable to say you’re going to enable someone. In any other context you’d get some weird looks just for saying that. </p>
<p>So what’s special about an enablement team? Typically that means developing and maintaining components that other teams can benefit from.</p>
<p>If you ship software to customers you’re probably dependent on a continuous integration system. If it goes down, then you’re pretty much dead in the water. So someone, or a team of people, have to maintain it and keep it running close to 24/7. </p>
<p>Can you imagine your company right now shipping without your CI system? If not, then the team that owns it is <strong>enabling</strong> you to do your job.</p>
<h2 id="heading-the-gatekeepers">The Gatekeepers</h2>
<p><strong>Gatekeeping</strong> is a word you don’t really hear much about. A gatekeeper is someone whose job is to not let anyone in to whatever they’re protecting. </p>
<p>The CI team is on the hook for its availability, they upgrade it from time to time, implement new features, fix bugs, apply security patches, etc. Given that everyone in the company depends on their work, it’s only natural to expect that they will always have a lot of planned work ahead of them. It’s common in a lot of companies that developers from other teams may be interested in helping them even though it’s not exactly their job to do so.</p>
<h2 id="heading-should-you-be-an-enabler-or-gatekeeper">Should you be an enabler or gatekeeper?</h2>
<p>Imagine you’re passionate about CI systems and you notice a problem with your company’s setup. It’s something you know how to fix, so you decide to just go ahead and do it. </p>
<p>After you’ve prepared your patch for submission there are really two different scenarios that could play out, and they have to do with values. Let’s see how the next steps would play out given two totally different teams, A and B, who uphold different values.</p>
<p>You talk to team A and they agree to review your patch. They suggest some improvements based on their experience, and work with you to deliver it. You gain more insights into what it means to actually be on the team. </p>
<p>You missed an edge-case and they point that out to you. You go back and fix it and re-submit, and your patch is finally accepted. They also let you know what’s coming down the road in the next months in case you find other issues.</p>
<p>You send your patch to team B. You don’t hear anything back for a couple of days, and decide to reach out in person. They tell you they’re swamped with work and don’t have time to look at your proposal. </p>
<p>You keep trying to convince them that it’s a small fix which greatly improves developer experience, but they don’t want to hear about it and finally tell you flat out that it’s not your job to think about CI. You give up and go back to work. Six months later they fix the issue but you only find out about it by accident.</p>
<p>Team B is what I’d call a <strong>gatekeeper</strong> team, even though their official mission is to enable, just like team A. They don’t let people in if they don’t have to. This team rarely benefits from the expertise of outsiders. It’s basically like comparing proprietary to open source. </p>
<p>But while I’m sure you’d rather interact with the former team, it may be useful to consider their perspective first before passing judgement.</p>
<p>It’s clear that team A values working together. If you bring an improvement to the table, they’ll take the time to review it, let you know if they were already planning on doing the same thing, or point out flaws in your solution. </p>
<p>Team B assumes that since you’re not on the team, you really have no business thinking about their line of work and you shouldn’t even try. But is team B’s behavior <em>objectively</em> bad? Like in all things software, it depends.</p>
<p>What if team B is maintaining a critical banking software component? If you were in their shoes, would you be so eager to let outside contributors in? What if your improvement contains a bug? If that happens it’s not your responsibility, you’re not on the team. They’re the ones who have to fix it. </p>
<p>Or perhaps their software is so complex there’s no way anyone on the outside would be capable of contributing without a lengthy on-boarding process.</p>
<p>You should also seriously consider that team A has to <strong>allocate time</strong> to work with you, so they’re making a call that you’re worth investing in. If it turns out your potential improvement would be a liability down the road, then they’re not getting that time back. It’s gone.</p>
<p>Team B in contrast is more draconian with their time. They consider themselves (perhaps rightfully so) experts in their field, and their assumption is, unless you’re on the team, you do not have enough context to suggest any improvements. You should only report problems to them and they’ll eventually get around to fixing them.</p>
<p>These are certainly extreme positions and I made them out to be so it’s easier to conceptualize. In reality teams are both enablers and gatekeepers, depending on the situation. But values always prevail, and it’s important to understand that when you need to work with other teams.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Remote Teams Guide: How to Manage Your Remote Software Development Team ]]>
                </title>
                <description>
                    <![CDATA[ By Alexandra Cote Guides to help you work remotely seem to have swept through the Internet these days.  Do this, avoid that, stay productive, and all those run-of-the-mill tips we’ve already tried out. So instead of talking about how your remote team... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/remote-teams-manager-guide/</link>
                <guid isPermaLink="false">66d45d5cb3016bf139028d09</guid>
                
                    <category>
                        <![CDATA[ Career ]]>
                    </category>
                
                    <category>
                        <![CDATA[ management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Product Management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ project management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ remote work ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 15 Apr 2020 15:48:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/remote-teams.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Alexandra Cote</p>
<p>Guides to help you work remotely seem to have swept through the Internet these days. </p>
<p><em>Do this</em>, <em>avoid that</em>, <em>stay productive</em>, and all those run-of-the-mill tips we’ve already tried out.</p>
<p>So instead of talking about how your remote team needs to schedule out their day effectively or clean their desk, <strong>here I am focusing on the hands-on tips you can apply to manage your software development team while working remotely.</strong></p>
<p>First, we need to understand the exact meaning of “remote teams”. </p>
<p>This will allow you to clearly see that having even one individual who’s working separately means you should improve the way in which you manage your team and the process they use for remote team collaboration and task execution.</p>
<h2 id="heading-what-are-remote-teams-really">What are remote teams really?</h2>
<p>Today, millions of companies are faced with <a target="_blank" href="https://mktodyssey.wordpress.com/2019/12/09/career-paths/">remote work</a> situations in one form or another. Whether they’re fully-distributed organizations, have a couple of employees working from another part of the world, or just regularly work with external collaborators.</p>
<p>The first thing that comes to your mind when you think of remote teams is something like: different people working from all parts of the world and distinct time zones on a single project and having the same general goals.</p>
<p>In reality, there are many remote teams that have employees in a single country or even in one city. It’s just that everyone works from their own home, without having to go to the office. ? This saves on costs while managing remote teams.</p>
<p><img src="https://lh4.googleusercontent.com/845bx8-McvMV-Pkl8NjnTX2Ihf7QaDh_xpqsfgwuAML1pE25KL9wRMIwZGvtN5koYBSd7VMB1YVNj33oPAOKzd2XVQ3bi_1I-E-0AtY04pkQDg8QmBr9dQHFM3ZqXonITVhIXMbW" alt="managing remote teams" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://giphy.com/gifs/yosub-money-donald-duck-cash-xTiTnqUxyWbsAXq7Ju">Source</a></em></p>
<p>But many companies (software development included) have offices in multiple countries. When your US team members talk to their colleagues from the UK, they’re essentially collaborating remotely. So remote team communication is a must in these cases even if everyone is in the office. </p>
<p>This being said, whether work is done from an office or not is not necessarily a defining factor for remote teams. The problems you could experience lie solely within the communication and work processes.</p>
<h2 id="heading-best-practices-for-managing-remote-software-development-teams-across-multiple-time-zones">Best practices for managing remote software development teams across multiple time zones</h2>
<p>Since you’re probably used to all the “<em>do this to be productive</em>” rants, I’ll try to tell you what you might not know.</p>
<h3 id="heading-hire-the-right-people-for-your-remote-teams">Hire the right people for your remote teams</h3>
<p>People are the heart of any team.</p>
<p><strong>So if you hire the right professionals [and humans] for your team, you’re halfway to success.</strong></p>
<p>On the hiring and interviewing process, here are some of the best tips from Shannon Hogue, Global Head of Solutions Engineering, @<a target="_blank" href="https://karat.com/">Karat</a>:</p>
<blockquote>
<p>“I always tell hiring managers to start at the review and work back to determine which core competencies should be listed in a job description. Then, to keep things standard across a global network of Interview Engineers, we put those competencies into structured scoring rubrics for each interview.  </p>
<p>Here are 3 quick steps for building a structured rubric that can help keep everyone on the same page, be it for hiring or managing:  </p>
<p>Identify what competencies are both relevant and important to assess.  </p>
<p>For each competency, list observable behavior and results as checkboxes (select all) and/or radio buttons (choose one).  </p>
<p>Write down an “algorithm” to help interviewers summarize a completed rubric into a single conclusion.  </p>
<p>For example, if Technical Communication is a relevant competency you might list it on the rubric with a specific scale.”</p>
</blockquote>
<p>Here’s what Shannon’s example could look like:</p>
<p><img src="https://lh5.googleusercontent.com/nN0XsdRv1_DL-PP2-__qTXI9SmBxHR11s5AcMgYUtL9S27TW_4i0lafGRVvhlg2js3tATGVhZny-kP5PzkuuNctsFcq8T-G9vZHLVpQAlUYcnQZBvESOTFmzHhQNz_raPokKiM4x" alt="remote teams communication" width="600" height="400" loading="lazy"></p>
<p><strong>Beyond any hiring tip, effective remote work also imposes a question on whether your office workers will</strong> <a target="_blank" href="https://www.entrepreneur.com/article/347376"><strong>adapt to the new lifestyle</strong></a><strong>.</strong> </p>
<p>If you’re switching from an office team to a distributed one or even if you want to hire someone who hasn’t worked remotely before, you need to guarantee they’ll fit in the team and work efficiently in your remote team even before day #1.</p>
<p>For software developers the demand is so high that you’ll often bump into this problem:</p>
<p><em>How do I make sure that who I’m hiring is the perfect fit within our team when they haven’t worked remotely at all?</em> ?</p>
<p>Perhaps tech professionals are some of the easiest to assess beforehand. Check out any of their side projects, if they own a business or do freelancing, and even look at their online presence. </p>
<p>A developer who’s only been putting work for their official job and has no GitHub repositories and projects to boast is clearly not going to be someone you’ll trust right away.</p>
<p><strong>Trust and accountability are the 2 main attributes to consider beyond any hard skills.</strong> </p>
<p>These two character traits (which we often ignore because we’re too focused on business results) can predict whether that person will fit within your team culture. And, even more importantly, if they’re willing to stay with your company for many years to come and dedicate themselves to your project.</p>
<p>From then on, managing remote teams is also a matter of how you handle their training.</p>
<h3 id="heading-onboarding-and-training">Onboarding and training</h3>
<p><strong>The trial period all HR experts recommend exists for a good reason.</strong> It allows you to literally SEE how they work, collaborate, and get along with the rest of the team.</p>
<p>Many managers make the mistake of hiring a developer, letting them start the trial weeks, but not monitoring what they’re actually doing. </p>
<p>Don’t assume that someone who seems skilled and experienced will deliver the same commitment and quality of work to you too. May I say this is the best and only time to be a micromanager and literally oversee all of their actions.</p>
<p><strong>But do offer your help within the first days by making sure they have all resources needed and making the appropriate introductions to your team.</strong> </p>
<p>Get them involved in the code writing process for your project as soon as possible so you can get a better feel of how they conduct their work. I’ll also advise you to try a pair programming session during the hiring process too. More on this procedure later in this guide.</p>
<h3 id="heading-prepare-the-right-work-methods">Prepare the right work methods</h3>
<p>This is largely the manager’s decision. Team feedback is only valid when everyone knows the relevant best practices and benefits of each work method. This doesn’t mean you can't get their input on the methods they’d prefer to use. However, letting them take care of the decision process will only give rise to conflicts and postpone the choice for the time being since there simply will be too many opinions for you to sort out.</p>
<blockquote>
<p>“While you do not want to micromanage a remote team, you certainly want to set up clear minimum administrative processes. For a previous remote team I had to manage, this included setting-up very precisely the infamous JIRA workflow.  </p>
<p>While it is good to leave a remote team some freedom, work also needs to be clearly organized, so there should be a few processes that have very precise descriptions. In development, the most important of such processes are issues management, and also the build process. This should be described in detail, and followed strictly.  </p>
<p>To make sure key processes are respected, there should be set points when work needs to stop until the process is followed. As an example, I gave strict orders to my business team not to look at any incident that is not documented.” - Nicolas de Mauroy, CEO @<a target="_blank" href="https://openlowcode.com/">Open Lowcode</a></p>
</blockquote>
<p><strong>But how close should supervision really be?</strong></p>
<p>Surprisingly – not that in depth. </p>
<p>Keep your devs under your radar only enough to guarantee that all processes run smoothly and you’re able to maintain a trust both ways. Yes, <a target="_blank" href="https://on.code42.com/go/2019-data-exposure-report-success/">50% of data breaches</a> across all industries are caused by insiders, but that doesn’t mean you must force everyone to track their time or record their screens.</p>
<p><strong>Developers should really only have to track their time in 2 instances:</strong></p>
<ol>
<li>They/you really want to improve your work processes.</li>
<li>They’re getting paid by the hour.</li>
</ol>
<p>Your role as a manager goes beyond the person who is seemingly in charge of everything. You’re a liaison. That key link between one team member and another, helping your development team collaborate with operations, marketing, design, customer support, and sales while also ensuring all team members are <a target="_blank" href="https://thriveglobal.com/stories/why-youre-not-happy-with-your-career/">happy</a> and their needs are met.</p>
<p>I’m super disappointed to tell you that only <a target="_blank" href="https://www.gallup.com/workplace/236552/managers-engaged-jobs.aspx">35% of managers</a> are engaged with their work. How is this going to motivate someone else? </p>
<p>Employees who are supervised by highly-engaged managers are in turn going to be better and happier performers themselves. This will boost your employee retention rates and create that long-lasting company-worker bond most companies can never attain.</p>
<p>This takes me to the importance of knowing when and how to communicate. Both ways.</p>
<h3 id="heading-craft-your-remote-team-collaboration-plan">Craft your remote team collaboration plan</h3>
<p>Collaboration goes hand-in-hand with your work method and how you manage tasks. It’s the little things like crafting clear task descriptions and expectations that add up to distinguish a positive collaboration experience from a chaotic one.</p>
<p><a target="_blank" href="https://www.linkedin.com/in/tinjothomasc/">Tinjo Thomas</a>, Design Technologist @Coredes Interactive also recommends the following two tweaks you can make:</p>
<blockquote>
<p>“1. Always set a due date for each task even though your developers are experts and can make estimates themselves.  </p>
<ol start="2">
<li>If you are giving instructions to only one or two people, don't send the message to the whole group. Reach out to every individual in private. People spend a lot of time reading unnecessary conversations on channels.”</li>
</ol>
</blockquote>
<h3 id="heading-on-meetings">On meetings</h3>
<p>Meetings are honestly a very controversial topic. Managers love to call meetings. Devs, though, hate most of them but are afraid to voice their thoughts.</p>
<p>To keep meetings relevant, here are some actionable points to keep in mind:</p>
<blockquote>
<p>“On a more macro-level, knowledge sharing can happen through a weekly team meeting with a Q&amp;A via video whereby the members of the team can share what they learned from the codebase with each other as well as ask questions. In terms of knowledge sharing through team meetings - you can have several types of meetings.   </p>
<p>The overall idea for these is to encourage collaboration in an effort to turn explicit knowledge into tacit knowledge. So you can have brainstorming sessions or meetings geared more towards lessons learned (this can be in the form of a demo or presentation). All done entirely remotely.” - Emil Hajric, CEO @<a target="_blank" href="https://helpjuice.com/">Helpjuice</a></p>
</blockquote>
<p>One huge mistake first-time remote team managers make is filling up entire days with meetings:</p>
<blockquote>
<p>“First-time remote team managers need to be quite aware of the differences between collaborative work [like Scrum meetings and software architecture design] and individual focus work [like coding]. It is important to schedule time and ensure everyone can contribute to the collaborative session, but then leave your professionals alone to do what they were hired to do, write great software.” - Pedro Henriques, Co-Founder &amp; CEO @<a target="_blank" href="https://www.bridgein.pt/">BRIDGE IN</a></p>
</blockquote>
<p>You’ll want to always remember to press that record button during meetings. We’re not necessarily fans of paper trails, but you’ll need them to avoid bothering your team with issues that have already been discussed:</p>
<blockquote>
<p>“You should be recording and saving absolutely everything from remote team meetings and strategy sessions. While working remotely, we've noticed a huge uptick in productivity when managers and team members can refer directly to meetings instead of having to play phone tag or email back and forth for simple information. It's a huge boon to workflow across the board and should really become the new normal with the increase in remote team management.” - Alexander M. Kehoe, Co-Founder and Operations Director @<a target="_blank" href="https://caveni.com/">Caveni</a></p>
</blockquote>
<p>Keeping up-to-date with all changes is even more important when your team’s distributed. But remote teams have different approaches to how they make sure they don’t just communicate, but also apply and consider every opinion.</p>
<p>Here’s where the real-time vs asynchronous communication battle comes in. Everything’s already been said about this. So the conclusion is:</p>
<p><strong>There’s a right time for each type of communication.</strong> A predisposition for certain types of tasks will also make your remote team more likely to go for one method of communication over the other.</p>
<p>Just like the video vs written communication issue.</p>
<p>The Voro team, for instance, has used their office and remote communication tests to conclude that written collaboration worked best for them:</p>
<blockquote>
<p>“My #1 tip for managing a remote team is to default to written communication rather than video calls. This forces you to clarify your thinking and communicate succinctly. When we all worked in the same office, it was easy to walk over to someone’s desk to talk through a problem. It would waste a great deal of time to replicate that with a scheduled video call.  </p>
<p>Since we are 100% remote, more of our communication has been written, and we try to memorialize most of that in internal documents, so we continue to move fast and share institutional knowledge seamlessly.” - Tomas Hoyos, CEO @<a target="_blank" href="https://www.voro.com/">Voro</a></p>
</blockquote>
<h3 id="heading-invest-more-time-in-one-on-ones">Invest more time in one-on-ones</h3>
<p>With one-on-ones, you’re focusing more on sharing the status of specific tasks and individual activities, while every single member on your team gets to make their own suggestions. One-on-ones are commonly held between one team leader and the other members at a time. </p>
<p>Having these twice a month is your best bet to make sure everything gets covered. Holding them weekly is too often as you won’t have time to focus on your other tasks because you’re too busy with meetings.</p>
<p>These one-on-one meetings are also a good opportunity for you to hold reviews and updates on the OKRs. To facilitate the feedback and ideation process, Charles Ahmadzadeh, CTO @<a target="_blank" href="https://bunch.ai/">Bunch</a> uses checklists during these meetings:</p>
<blockquote>
<p>“I like to use checklists with my team. I'll ask each team member to create a checklist each day of what needs to be done before ending the day and before submitting their work. We review these checklists in 1:1s to spot patterns.  </p>
<p>I mostly use this to help others around me grow or keep myself accountable to the feedback I receive from the team.  </p>
<p>The good thing about them is that they work no matter how senior you are (even astronauts live by checklists). They’re easy to share in 1:1, even if your team is remote, and very simple to use, as long as you’re committed to improving yourself.”</p>
</blockquote>
<p><strong>NOTE ON OBJECTIVES AND KEY RESULTS:</strong> Team leaders can establish these at a team and individual level by also taking into account suggestions from developers. </p>
<p>For instance, each department or team can have specific targets: to release a feature on time, avoid more than 2 major bugs after a release, keep the error rate low, etc. Individually, each member should take care of one release so that every single team member will know how to handle them. </p>
<p><strong>Here’s an actionable idea:</strong> Use <a target="_blank" href="https://trackjs.com/">TrackJS</a> [or other error tracking tool for your programming language]. Every member can choose a top error and fix it. This allows members to increase their accountability and learn new things to avoid freezing their skills.</p>
<h3 id="heading-pair-programming-finally-getting-the-attention-it-deserves">Pair programming finally getting the attention it deserves</h3>
<p><strong>Now is also the best time to experiment with pair programming.</strong> This practice allows two developers to work simultaneously, often on the same tasks. While this is usually done from the same computer, you can switch it up a bit and make use of tools like TeamViewer or screen sharing.</p>
<p>Pair programming also helps distributed teams improve the quality of their code, tighten bonds between colleagues, transfer information and know-how from one dev to another, increase their own accountability, and speed up the entire development process. </p>
<p>Does this make you feel like you’ve been missing out on all its benefits? ? Just keep in mind some best practices if you want to get started with using the pair programming practice on a regular basis. </p>
<p>By using common sense, you probably won’t have both developers working on the same thing for 8 hours straight. Instead, distribute tasks evenly and allot a specific time slot for them to actually work together. Dealing with multiple time zones? Pair programmers within similar work schedules.</p>
<h3 id="heading-communicate-beyond-work-with-your-remote-teams">Communicate beyond work with your remote teams</h3>
<p>We’re all humans. <strong>So we can’t work, work, work all the time.</strong> How about you implement some activities for people to destress twice a week as part of your remote team management process?</p>
<p>Playing board games online. Having a #watercooler channel on Slack. Finding some creative online team building activities. These are all ideas to help your remote teams unwind and get their mind off anything that’s stressing them out.</p>
<p>Pedro Henriques also shared his thoughts on the importance of implementing this type of downtime while working remotely:</p>
<blockquote>
<p>“Remote teams need to deliberately schedule slack time and create informal virtual watercooler moments. In the office, the watercooler or coffee machine is often the place for spontaneous discussions about various topics ranging from a nasty software bug to vent about office politics or even troubles in personal life. These discussions are not superfluous. They’re absolutely critical for team cohesion. Therefore managers should actively promote them, but make sure not to attend.”</p>
</blockquote>
<h3 id="heading-choose-the-right-tools-the-basics-will-do-there-are-no-magical-solutions">Choose the right tools: The basics will do, there are no magical solutions</h3>
<p>I’ve seen so many “best tools for remote work” lists the Internet could really crash for good.</p>
<p>Nah, but really, stop looking for the best apps and miraculous software to somehow save your remote teams.</p>
<p>We already know everyone is using Slack and Zoom to collaborate and the ones who don’t use these are probably doing so because of small issues they had or costs they wanted to lower. </p>
<p>For instance, from all apps I’ve tested for this purpose Google Meet was the fastest and most accurate one but guess what? My clients are using Zoom already. No room to impose another tool.</p>
<p>The key point is not to waste weeks trying to find the right tools for your team. Others have already done this. There are thousands of options out there. All of them are copying features from each other so you end up with the same tool in dozens of versions. </p>
<p><strong>So here’s your stack:</strong></p>
<p>Jira - Slack - Zoom - GitHub - InVision - a bug tracking tool - every developer’s code editor</p>
<p>Test these [preferably the free versions first] and only look for alternatives if you have huge issues that are stilting your workflow. My two cents.</p>
<p><strong>Also, some wise words from Tinjo Thomas:</strong></p>
<blockquote>
<p>“Don't try to save money on bug tracking or team management tools. You will know why it’s important when things don’t get done as you expected.”</p>
</blockquote>
<p><strong>Know a remote team manager who could use these tips?</strong> Share this remote team management article with your network to keep improving remote work processes.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Work From Home During the COVID-19 Pandemic: My Personal Tips ]]>
                </title>
                <description>
                    <![CDATA[ By Black Raven The COVID-19 coronavirus pandemic has resulted in many people working from home. So you might be wondering - how do I remain productive at home? Remote work has been on the rise for years in many companies. Some offer remote work as a ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/my-personal-tips-on-working-from-home-during-this-covid-19-season/</link>
                <guid isPermaLink="false">66d45ddbd7a4e35e38434943</guid>
                
                    <category>
                        <![CDATA[ business ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ remote work ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ working from home ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 29 Mar 2020 12:47:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/Screenshot_1-3.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Black Raven</p>
<h3 id="heading-the-covid-19-coronavirus-pandemic-has-resulted-in-many-people-working-from-home-so-you-might-be-wondering-how-do-i-remain-productive-at-home">The COVID-19 coronavirus pandemic has resulted in many people working from home. So you might be wondering - how do I remain productive at home?</h3>
<p>Remote work has been on the rise for years in many companies. Some offer remote work as a benefit to employees for better work-life balance. </p>
<p>And today, millions of people around the world have recently started working from home (WFH) because of the COVID-19 coronavirus outbreak.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_vXJxKwdw1FwVJo_XdsXsWg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Some companies do not advocate for WFH as they believe people cannot work without supervision. Instead, they adopted a controlling and micro-management culture. </p>
<p>However, which is a more productive environment for employees? The home office or the <em>office</em> office? Well, it looks like we have the opportunity to find out.</p>
<p>The situation may extend for weeks or even longer. Nonetheless, it is a great opportunity for a lifestyle change. There will be no rushing to leave home and skipping breakfast so that you won't miss the train.</p>
<p>A joint report by <a target="_blank" href="https://lp.buffer.com/state-of-remote-work-2020">Buffer and Angellist</a> surveyed more than 3,500 remote tech workers. It found that the top benefits of WFH are a flexible schedule, the ability to work from anywhere, and not having a commute.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_LdeJjnvk0c2B2fn58LDs1Q.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the other end of the scale, the challenges of team collaboration and communication become apparent when team members are dispersed in isolation. They also feel constantly attached to work while distracted by things at home.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_UDnKoVhEVYVuKgezuEhh3g.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>WFH is awesome. To some, it may seem like newfound freedom, but along with it comes responsibility as well. To help with the transition into this new way of working, here are some useful tips:</p>
<h2 id="heading-daily-routine">Daily Routine</h2>
<p><strong>Be disciplined</strong>. It is important to cultivate strict routines or working hours, but also be kind to yourself. Wake up at your usual time and go through your usual routine. For me, I use the time usually spent on commuting to read or stretch my legs.</p>
<p><strong>Dress properly</strong>. Do not wear pajamas. The way you dress can influence your mood and attitude, so dress in proper work attire.</p>
<p><strong>Set work hours</strong>. WFH allows for flexibility, but the start and end of your work day should be as routine as possible. Enforce a hard stop at the end of the day, and plan for personal errands after that. Setting a target end time will dictate expectations and increase productivity.</p>
<p><strong>Create a good routine with short exercise breaks</strong>. I personally feel that moving and stretching my body energizes the brain. The truth is, endorphins are produced when exercising, which increases happiness and interest levels.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_6yRUScwaEi8u1zNWPeB_yg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-communication">Communication</h2>
<p><strong>Have a daily standup meeting with your team</strong>. This can be done remotely (whether standing or sitting). Just maintain the essence of keeping it short, and keeping team members accountable to one another in their respective tasks.</p>
<p><strong>Have more social interactions</strong>. WFH can be lonely, so I do plan virtual coffee breaks with co-workers (with a real fragrant cup of coffee). Keep talking to people so you do not feel isolated.</p>
<p><strong>Over-communicate</strong>. WFH means I cannot walk by a colleague to say something. If the matter is urgent, I usually do redundancy in communication. For example, after an email is sent, I also send a text message to the recipient, or leave a ping on Slack.</p>
<p><strong>Use emoji</strong>. Text messages usually look more formal and serious on their own. To keep messages positive, sometimes I like to lighten the mood by adding a smiley face. There's a world of difference between saying DONE and done :-).</p>
<h2 id="heading-distractions">Distractions</h2>
<p><strong>Keep the television turned off</strong>. It is a big distraction. The radio or music on YouTube might be better if you are the type who works well with some background music. Relaxing jazz creates an unwinding mood, whereas video game soundtracks keep the energy level high.</p>
<p><strong>Stay off</strong> s<strong>ocial media</strong>. We are <em>all</em> guilty of this one from time to time, and social media can be one giant time-waster if you're not careful.</p>
<p><strong>Separate space to work from space to rest</strong>. You should not work in the bedroom (the bed is so comfy! And it gives you backaches), and also not in the kitchen (You have full access to all the snacks! And it upsets your diet).</p>
<p><strong>Leave Home</strong>. If temptations are too distracting, go to a WiFi-enabled cafe like Starbucks. A new environment is also a great stimulant for creativity and attention.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_DnLbpMHogSJhtY8ioy6VUA.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-time-management">Time Management</h2>
<p><strong>Keep a daily checklist</strong>. Whether you work in the office or from home, it is essential to set a schedule for the day and keep track of daily tasks.</p>
<p><strong>Use online tools</strong>. There's a lot of free software to improve productivity:</p>
<ul>
<li>Video conference: Skype, Zoom, Google Meet, Cisco Webex</li>
<li>Tasks and project management: <a target="_blank" href="https://airtable.com/">Air Table</a>, <a target="_blank" href="https://www.novatools.org/">NovaTools</a>, <a target="_blank" href="https://trello.com/">Trello</a></li>
<li>Team communication: Whatsapp online, Slack, Workplace by Facebook</li>
<li>Shared documents: Dropbox, Box, GoogleDrive</li>
</ul>
<p><strong>Schedule frequent short breaks</strong>. Although taking breaks might seem counterproductive, research has shown that taking short breaks can actually increase productivity and creativity levels. Go get some fresh air <strong>outdoors</strong>, listen to the birds, enjoy the breeze, take time to smell the flowers, connect with nature with a short walk or cycle.</p>
<p><strong>Avoid work creep</strong>. WFH can be invasive to your personal life. Without scheduled work hours, work can creep into your home life and just like personal errands can creep into work hours. Do not mix household chores into work hours.</p>
<h2 id="heading-workspace-logistics">WorkSpace Logistics</h2>
<p><strong>Prepare a conducive workspace</strong>. Apart from having a high-speed internet connection and a reliable router, get a comfortable chair and reserve a quiet space to be able to do focused work. </p>
<p>I have converted the guest room into a home office with ergonomic chairs, extended monitor screens, a full suite of stationery, and a printer. Most importantly, it is well lit and ventilated.</p>
<p><strong>Use a comfortable headset or earpiece for calls</strong>. It is a good habit to mute your microphone during conference calls (unless you’re speaking) to minimize the amount of audio feedback and random sounds that interrupt the conversation. </p>
<p>Other hacks include: lower the video resolution when the network traffic is heavy, and use a collaboration tool to share your screen but get audio through the phone.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/1_Znlr5cQ-nKTW1695CdeSbg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-for-parents">For Parents</h2>
<p><strong>Keep children in your plans</strong>. Due to school closure, children may also be around at home. Plan and schedule some activities to occupy them while you work.   </p>
<p>Have staggered lunchtime to spend with children; for instance, one partner can have a lunch break at 11 am-12 pm, and the other breaks at 12 pm-1 pm, so 2 hours are spent with children.   </p>
<p>For all we know, working with children around us might become the new norm from this season on.</p>
<p><strong>Get family support</strong>. I am fortunate to have my mum to watch over the little ones during the day, along with a domestic helper to do the chores so my wife and I can focus on work.</p>
<h1 id="heading-this-can-be-a-good-thing">This can be a good thing.</h1>
<p>WFH is great for work-life balance. It increases ownership and performance. It trains people to be focused and disciplined. I look forward to seeing the productive benefits of trust and empowerment.</p>
<p>Everyone’s situation is different in terms of home environment, personality and habits. My advice is to ignore any tips that clash with your personal beliefs. Tailor the most effective way of working for you and keep practicing until it becomes part of a lifestyle or culture.</p>
<p>“<a target="_blank" href="https://www.brainpickings.org/2014/01/02/how-long-it-takes-to-form-a-new-habit/">It takes 21 days to form a habit</a>”</p>
<p>Once a new way of working has been established all over the world, it might be hard to go back to the old ways.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Programmers Don't Have to be Socially Awkward. Here Are 10 Social Skills To Improve Your Career. ]]>
                </title>
                <description>
                    <![CDATA[ If you work as a software developer, most of your workday is spent dealing with people. Immediately when you start your work for the day, you probably check email, Skype, or Slack, as you are interested in seeing if your work colleagues have somethin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/programmers-dont-have-to-be-socially-awkward/</link>
                <guid isPermaLink="false">66d45f059208fb118cc6cf9f</guid>
                
                    <category>
                        <![CDATA[ career advice ]]>
                    </category>
                
                    <category>
                        <![CDATA[ soft skill ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fatos Morina ]]>
                </dc:creator>
                <pubDate>Wed, 21 Aug 2019 04:17:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/08/Napoleon-Dynamite.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you work as a software developer, most of your workday is spent dealing with people.</p>
<p>Immediately when you start your work for the day, you probably check email, Skype, or Slack, as you are interested in seeing if your work colleagues have something important to tell you.</p>
<p>Then, when you write a response, the destination for your words is another person, not just another computer.</p>
<p>Your main priority at work is to solve problems, which is done while collaborating on projects and hanging out with other people as part of a software development team.</p>
<p>You attend meetings during the day and get the implementation requirements from other people.</p>
<p>When you are finally ready to do one of the most enjoyable activities for a software developer, which is writing code, you are supposed to write a code which is primarily readable for humans. You do not write your software projects in binary codes, but instead in a programming language that is supposed to be easier for both you and teammates to understand.</p>
<p>Even if you are working at a small company, or are a freelancer, you still have to deal with the non-technical people in the project that you are working on.</p>
<p>We spend a lot of our waking hours with our work colleagues. It is even possible that we spend more time with them than with our close family members.</p>
<p>Becoming aware of this will help you realize the importance of having good relationships with others, especially your co-workers.</p>
<p>In this article, you can read some general tips that can help you improve your relationships at work, but that can be applied elsewhere as well.</p>
<p>They are simpler to follow than the frameworks used to develop your applications, but these tips have a huge potential for return over investment.</p>
<h3 id="heading-1-be-very-kind"><strong>1. Be very kind</strong></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-236.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Photo by [Unsplash](https://unsplash.com/@mimithian?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Mimi Thian / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit)</em></p>
<p>You can be the smartest and the hardest-working person you know, but when you do not have good manners or you lack kindness, others in your workplace might hate collaborating with you. Not because you lack the skills and the ability to write clean and maintainable code, but because of your attitude.</p>
<p>No matter how frustrating a bug is, do not pout, whine, or yell at your colleagues. Those bad manners will not be able to fix your bug. It can even harm your personal and professional relationships and make it very difficult to get back on track later on.</p>
<p>When you are kind, you are more likely to make a good impression on others as a human being in general.</p>
<p>Simple acts of kindness, such as giving someone a ride to or from work, mentioning someone’s favor in front of others, cleaning up a colleague’s space that’s not your job to keep clean, etc., should be done repeatedly, despite knowing your colleagues for a long time.</p>
<p>Your kindness will trigger, at least, a basic human decency from your colleagues as well.</p>
<h3 id="heading-2-always-be-genuinely-interested-in-your-colleagues"><strong>2. Always be genuinely interested in your colleagues</strong></h3>
<p>Try to understand if they need your help, and do not hesitate to kindly help them. When you see that they are stressed, anxious, or going through tough times, talk to them and show readiness to brainstorm solutions about the problems they are involved in.</p>
<p>Even if you cannot help them with their current task, try to encourage them with motivational phrases that can uplift them emotionally. Make them feel that they are important to the team and capable of overcoming the obstacles they’re facing and the down times they might be in.</p>
<p>Your words alone can magically improve the mood of your colleagues.</p>
<h3 id="heading-3-smile-often"><strong>3. Smile often</strong></h3>
<p>Even printing a ‘Hello world’ statement takes more time and effort than smiling and sending smiley emoticons. It may seem trivial, but smiling can lighten up the tension.</p>
<p>A <a target="_blank" href="http://blackburnelrodortho.com/how-smiling-affects-you-and-those-around-you/">scientific study</a> conducted in 2011 at the Face Research Laboratory at the University of Aberdeen in Scotland found that smiling makes you feel more attractive, relaxed, sincere, and confident.</p>
<p>Moreover, <a target="_blank" href="http://blackburnelrodortho.com/how-smiling-affects-you-and-those-around-you/">one Swedish study</a> published in the Scandinavian Journal of Psychology found that humans have an automatic reaction that mimics the facial expressions of those they interact with.</p>
<p>In other words, when you smile often, chances are that others will smile back to you as well. This will not only make you feel better, but it also helps others that you interact with.</p>
<h3 id="heading-4-say-thank-you-and-please-a-lot"><strong>4. Say ‘thank you’ and ‘please’ a lot.</strong></h3>
<p>No matter how small a favor is, do not hesitate to say <em>thank you</em>.</p>
<p>People appreciate when you are polite and grateful, and are aware of their contribution and significance in your life.</p>
<p>This will not only make your colleagues feel better, but it will make you feel better as well, as you will know that other colleagues care about you and are willing to help you.</p>
<p><a target="_blank" href="https://www.forbes.com/sites/amymorin/2014/11/23/7-scientifically-proven-benefits-of-gratitude-that-will-motivate-you-to-give-thanks-year-round/#4463c9d0183c">Gratitude can improve your physical health</a>, mental strength, self-esteem, the quality of your sleep, and can even reduce your stress levels.</p>
<p>Another word that you should frequently use in your communication with your colleagues is <em>please</em>.</p>
<p>When you use the word <em>please</em>, you are reminding the other team member that he is not forced to do something, but it would be kind, generous, and helpful of him to assist with the task that you are working on.</p>
<p>These simple words, no matter how insignificant they may sound, can make a huge difference once you start using them.</p>
<h3 id="heading-5-praise-other-peoples-efforts-and-stay-positive"><strong>5. Praise other people’s efforts and stay positive</strong></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-237.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Photo by Tyler Nix on Unsplash</em></p>
<p>Become aware of other people’s accomplishments and praise every improvement, large or small.</p>
<p><strong>Praising someone isn’t complicated. Common phrases like “Great job,” “Well done,” or “You did great” can be sufficient.</strong></p>
<p>It may have taken a lot of effort and strong willpower to get to the solution of a frustrating problem.</p>
<p>When you praise others on their accomplishments, you make them feel important and that they are involved in something that has grabbed your attention.</p>
<p>As software developers, we tend to forget about the privilege of the skills we possess.</p>
<p>There are times when a small bug or an urgent task can bother you or your colleague for a few moments, but you should not let that distract you from the big picture.</p>
<p>You should regularly remind yourself and your colleagues about the joyful moments that you and your team have been through, and not let an occasional difficulty or a stressful situation make you feel disappointed.</p>
<p>Start the habit of regularly recognizing the efforts of your teammates and giving credit to them whenever the opportunity arises.</p>
<h3 id="heading-6-do-not-hesitate-to-apologize"><strong>6. Do not hesitate to apologize</strong></h3>
<p>Nobody is perfect, and no matter how hard you try, you will always make a mistake here and there.</p>
<p>No matter how small your mistake is, do not hesitate to apologize about it.</p>
<p>Even though it might threaten your ego to apologize sometimes, it is a crucial way to keep good relationships with your colleagues.</p>
<p>Although you may think it will damage your reputation, by causing you to appear less confident, apologizing has the opposite effect.</p>
<p>It will remind others that you are aware of your shortcomings and that you are humble enough to admit to them.</p>
<p>Short phrases like “I am sorry” or “I apologize” can strengthen your ties with your colleagues, even during unpleasant moments.</p>
<h3 id="heading-7-do-not-criticize"><strong>7. Do not criticize</strong></h3>
<p>Criticizing is often perceived as a personal threat towards an individual’s ego, though you may not have intended to do that.</p>
<p>As a result, it is likely that they may get emotional and feel offended.</p>
<p>A better way of pointing out your colleague’s mistake is by giving them a <em>polite critique</em>: Call attention to people’s mistakes without demeaning them or making it personal.</p>
<p>Put yourself in their shoes and observe the issue from their perspective. Politely inform the other person about their mistake.</p>
<p>Do not point out a mistake in front of everybody; instead, do it privately.</p>
<p>If you want to inform everybody else about a mistake that they should not be doing, do not point fingers toward people, but toward the problem.</p>
<p>Try to focus on possible ways of solving the problem rather than on blame.</p>
<p><strong>Become the person who helps people, rather than someone who belittles them.</strong></p>
<p>When you help someone, you are going to feel your own sense of contributing and your own significance as well. Moreover, you can learn for yourself, and can also open doors to receiving help in future from the same colleagues that you have helped in the past.</p>
<h3 id="heading-8-avoid-arguments"><strong>8. Avoid arguments</strong></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-238.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Photo by [Unsplash](https://unsplash.com/@jasonrosewell?utm_source=medium&amp;utm_medium=referral" rel="photo-creator noopener"&gt;Jason Rosewell on &lt;a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="photo-source noopener)</em></p>
<p>We tend to think of ourselves as rational human beings, but in reality, we are emotionally driven creatures that can easily get angry.</p>
<p>Those few moments of anger can lead to some unpleasant arguments, no matter whether you are right or wrong.</p>
<p>Although you may be right, and protecting your opinion sounds like a good idea, arguing furiously with others is something that can dramatically ruin your relationships.</p>
<p>As Dale Carnegie mentions in his book <a target="_blank" href="https://www.amazon.com/How-Win-Friends-Influence-People/dp/0671027034/ref=sr_1_1?ie=UTF8&amp;qid=1491286020&amp;sr=8-1"><em>How to Win Friends and Influence People</em></a>:</p>
<blockquote>
<p><em>“I have come to the conclusion that there is only one way under high heaven to get the best of an argument — and that is to avoid it. Avoid it as you would avoid rattlesnakes and earthquakes.”</em></p>
</blockquote>
<p>The best thing to do about arguments is to try your best to avoid them at all costs. It is not as easy as it sounds, but it can become easier with practice.</p>
<p>Reminding yourself that most of the time there is almost no benefit from arguing, especially with your work colleagues, can reinforce the desire to keep yourself away from arguments.</p>
<h3 id="heading-9-ask-questions-instead-of-giving-direct-orders"><strong>9. Ask questions instead of giving direct orders</strong></h3>
<p>This is something that is more relevant to team leaders or managers, but it can apply to anyone else as well.</p>
<p>People tend to be more inspired to work when they are challenged to do something, rather than ordered around.</p>
<p>When you command someone to do something, their ego may come out and make the individual think that he is being oppressed or that his autonomy is being threatened.</p>
<p>Rather than giving a direct order, ask whether a colleague would like to work on a particular task.</p>
<p>If there is no other available developer who can work on a particular task, and you are afraid that they may not like working on the front-end side, tell them you are worried that the team might look bad in front of the client if this feature is not present in the next meeting.</p>
<p>Questions like “<em>Would you mind working overtime and finishing off this task, knowing that this is critical for our project?”</em> are better than commands like <em>“You cannot go home unless you get this task done.”</em></p>
<p>Mention to them that they are an important part of the team, and they can help the team prove to the client that they are reliable for future projects as well, with questions such as, <em>“Could I possibly assign this task to you, knowing that you are already experienced with these types of work?”</em></p>
<h3 id="heading-10-avoid-dealing-with-toxic-people"><strong>10. Avoid dealing with ‘toxic’ people</strong></h3>
<p>Even though working as a software developer might be your dream job, there may nevertheless be toxic people at your workplace.</p>
<p>You thought you left those types of people behind at your high school, but it turns out that life is filled with so many of them.</p>
<p>These people are simply looking for opportunities to bring others down and may generally possess a negative perspective on everything in life.</p>
<p>You can try to change them with your well-intentioned influence, but often it is very difficult for a person to change (for a lot of reasons).</p>
<p>If you see that you are not having any positive influence, and associating with them is only causing you trouble, then you should avoid dealing with them.</p>
<p>You might be in a situation, however, where this person is your manager or a colleague in your office.</p>
<p>In these cases, your alternatives are very limited. You may consider changing your department, or start looking for a new job.</p>
<p>In cases when you do not have any other alternative but to deal with them, prepare yourself mentally ahead of time regarding their bad attitude, and tell yourself that you should not let them influence your mood and ruin your whole day.</p>
<p>Their attitude is not something that should surprise you.</p>
<p>Try to interact with them as little as possible.</p>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>There is a lot more to the life of a software developer than just writing code. Dealing with people is one of the key factors.</p>
<p>Although they do not get mentioned or emphasized that much, social skills are among those few seemingly unimportant skills that can actually accelerate growth in your career.</p>
<p>And they are much simpler to understand and put into practice than inverting a binary tree on a whiteboard.</p>
<p>While I agree that some of these things are easier said than done, it is important to practice applying them in our lives.</p>
<p>Before you leave, let me kindly remind you about one more thing: <strong>Do not expect to always be able to apply these things all of the time</strong>.</p>
<p>We are human beings and we have our own difficult times, too.</p>
<p>However, we must not let those few moments of frustration and anger ruin our whole professional and non-professional lives.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to get your team on board with accessibility ]]>
                </title>
                <description>
                    <![CDATA[ By James Y Rauhut We all learn about web accessibility at different points in our career. That means a lot of time you are not on the same page as your teammates. I had the privilege a couple of months ago to speak at Pingboard about accessibility. O... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-align-your-team-on-the-need-for-accessibility/</link>
                <guid isPermaLink="false">66d460f451f567b42d9f84a7</guid>
                
                    <category>
                        <![CDATA[ a11y ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ presentation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ progressive web app ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 13 Aug 2019 21:40:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/08/keyboard-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By James Y Rauhut</p>
<p>We all learn about web accessibility at different points in our career. That means a lot of time you are not on the same page as your teammates. I had the privilege a couple of months ago to speak at <a target="_blank" href="http://pingboard.com/">Pingboard</a> about accessibility. Our goal was to get the whole team at the same knowledge starting point. If we all have a basic understanding of whom web accessibility affects and how it affects them, we can ship better experiences.</p>
<p>You probably find yourself in the same opportunity at your company to present on accessibility. So I would like to do two things to help: I am going to <a target="_blank" href="https://drive.google.com/file/d/1W62aya8uk0LgMPyMUBSIAJVOQBewmiKd/view?usp=sharing">give you my presentation</a> as a starting point and walk you through the points I like to touch on.</p>
<blockquote>
<p>You probably find yourself in the same opportunity at your company to present on accessibility. …I am going to <a target="_blank" href="https://drive.google.com/file/d/1W62aya8uk0LgMPyMUBSIAJVOQBewmiKd/view?usp=sharing">give you my presentation</a> as a starting point and walk you through the points I like to touch on.</p>
</blockquote>
<h1 id="heading-remind-the-team-that-you-are-talking-about-real-people"><strong>Remind the team that you are talking about real people.</strong></h1>
<p>When we read accessibility documentation, it is easy to forget the human element. It makes sense because you are reading technical docs meant to influence code. It is great to start with this shared definition:</p>
<p><strong><em>A person with a disability:</em></strong> <em>A person who has a physical or mental impairment that substantially limits one or more major life activity.</em></p>
<p>We use this to establish friendly dialog. People do not want to be called “disabled”. They want to be called their name. We also need to clarify how wide of a range disabilities can be. Try expanding past assumptions early on with these points:</p>
<ul>
<li>Some disabilities come at birth, some come later.</li>
<li>Some disabilities are permanent, some are temporary.</li>
<li>Some disabilities always affect, some come and go.</li>
<li>Some disabilities are visible, some are invisible.</li>
</ul>
<h1 id="heading-go-over-some-disability-categories-with-emotional-experiences-and-quick-tips"><strong>Go over some disability categories with emotional experiences and quick tips.</strong></h1>
<p>Now that we have established that we are talking about people, it is time to talk about their experiences. I like to mix this section with quick tips for common disability categories. Remind your audience that there are way more disabilities than you are covering. They are difficult to categorize, which is why the technical documentation focuses on the solutions.</p>
<p>Something you will notice about the presentation is that there is a lot of video and audio. I find it more effective to have those with disabilities speak more than me about the issue. The multimedia in the presentation makes it possible for those people to not even have to be there.</p>
<h3 id="heading-visual">Visual</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/UzffnbBex6c" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>I love to share this video of Tommy Edison using a screenreader because he keeps things lighthearted, but also goes through the whole process of sending an email. After the video, you can point out that fellow Mac users can try their screenreader with <code>CMD + F5</code> at anytime.</p>
<p>Quick tips:</p>
<ul>
<li>People with dyslexia prefer to override font settings.</li>
<li>People with low vision need to be able to zoom correctly.</li>
<li>People with color blindness need an overall color contrast ratio of 4.5:1. Text 19px or larger can have a ratio of 3:1.</li>
<li>People with color blindness need labels and patterns for differentiations.</li>
</ul>
<h3 id="heading-auditory-and-seizure">Auditory and Seizure</h3>
<p>Auditory disabilities are easier to talk about with digital product teams. Remind your team that all audio should be paired with visual cues and captions. Encourage the team to do content audits to check all videos for closed captioning.</p>
<p>Strobing, flickering, and flashing can trigger seizures. Other triggers include animations longer than 250ms, parallax, and images moving under text.</p>
<h3 id="heading-motor">Motor</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/yx7hdQqf8lE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>There are two demos I like to show teammates when it comes to motor disabilities. The first is hidden inside a longer video. A fellow named Gordin Richins shows what it is like to use a mouth stick. It is an older video, but I try to point out that new technologies can be more expensive.</p>
<p>The second video is a wholesome video of an eye tracking product. These are great because they can provide mouse capabilities to those with motor disabilities. However, we should still make all experiences keyboard accessible to be safe.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/FEQv7buTNxw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-cognitive">Cognitive</h3>
<p>Cognitive disabilities can be difficult to convey. For this last category, I stuck with quick tips to keep the presentation alternative between facts and emotion. Here are the quick tips I share:</p>
<ul>
<li>For memory, keep processes short and remind users of context as much as possible.</li>
<li>For problem-solving, error messages should be as explanatory as possible.</li>
<li>For attention, use visual cues to highlight the most important points or sections of content.</li>
<li>For reading, linguistic, and verbal comprehension, provide supplemental media that helps processes.</li>
</ul>
<h1 id="heading-emphasize-how-common-disabilities-actually-are"><strong>Emphasize how common disabilities actually are.</strong></h1>
<p>Did you know that one out of five people in the US have at least a one disability? (<a target="_blank" href="https://www.census.gov/newsroom/releases/archives/miscellaneous/cb12-134.html">source</a>) It may not seem like that in the workplace, but we should consider why. This is the point of the presentation when people should understand invisible disabilities. Invisible disabilities can be hidden from the naked eye. Here is a great interview where Carly Medosch talks about working with an invisible disability:</p>
<p><a target="_blank" href="https://www.npr.org/2015/03/08/391517412/people-with-invisible-disabilities-fight-for-understanding"><strong>NPR: People with 'Invisible Disabilities' Fight for Understanding</strong></a></p>
<p>This story is a great transition to a big question: What can we as enterprise software teams do to help those with disabilities?</p>
<p>Well, 79% of people of a working age in the US have employment. Only 41% of people of a working age in the US that have disabilities have employment. (<a target="_blank" href="https://www.census.gov/newsroom/releases/archives/miscellaneous/cb12-134.html">source</a>) If more jobs were accessible, that gap would close. This means that we as enterprise software teams can make it our mission to close the gap!</p>
<h1 id="heading-end-with-the-legal-risk-for-those-that-need-extrinsic-motivation"><strong>End with the legal risk for those that need extrinsic motivation.</strong></h1>
<p>It may not feel great, but some people may still need more reasoning about why the team should work towards accessible experiences. This is why I like to close the presentation on the legal implications of accessibility.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/Screen-Shot-2019-08-13-at-3.45.32-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>ADA Title 3 lawsuits in federal court: 2722 in 2013, 4436 in 2014, 4789 in 2015, 6601 in 2016, 7663 in 2017, 10163 in 2018. https://www.adatitleiii.com/2019/01/number-of-ada-title-iii-lawsuits-filed-in-2018-tops-10000/</em></p>
<p>In 1990, the Americans with Disabilities Act was signed. This provides those with disabilities the same protection that’s given in the Civil Rights Act of 1964. Section 508 says digital experiences in government departments and agencies have accessibility requirements.</p>
<p>Lawsuits continue to grow saying that the ADA also covers digital experiences from any company. Over 10,000 lawsuits were filed in 2018 alone. In fact, one of those <a target="_blank" href="https://www.cnbc.com/2019/07/25/dominos-asks-supreme-court-to-say-disability-protections-dont-apply-online.html">cases is headed towards supreme court</a>.</p>
<h1 id="heading-be-a-part-of-the-good-fight">Be a part of the good fight.</h1>
<p>Are you considering presenting to your team on web accessibility? You really should. You don’t have to be an expert and it’s okay if not everyone listens to you. Every effort to make the web a more friendly place is worth it.</p>
<p>I hope these resources helped you shape a future presentation. Please steal everything from me (but keep the citations).</p>
<p>If you appreciate this, please consider voting for my SXSW talk idea. I want to teach product managers, designers, and everyone else about progressive web apps. The cool thing about PWAs, is that a lot of accessibility criteria is baked in! If you wanna learn more, check out the video below.</p>
<p><a target="_blank" href="https://panelpicker.sxsw.com/vote/95517">Please take minute to vote for my talk and share it with others.</a></p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/aRwfB7Iiaqo" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Got any other good resources for accessibility presentations? Please share them in the comments or tweet me them at <a target="_blank" href="http://twitter.com/seejamescode">@seejamescode</a>. I will retweet the best ones!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A zen manifesto for effective code reviews ]]>
                </title>
                <description>
                    <![CDATA[ By Jean-Charles Fabre When you are coding, interruptions really suck. You are in the zone, flying high, killing it. And BAM… meeting, standup, insert interruption… Great! In that context, code reviews can be perceived as another hurdle to productivit... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-zen-manifesto-for-effective-code-reviews-e30b5c95204a/</link>
                <guid isPermaLink="false">66c3437452e2abc555bfcbf7</guid>
                
                    <category>
                        <![CDATA[ code review ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 02 May 2019 20:30:34 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*Pt73-k3YNsgjnOP8" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jean-Charles Fabre</p>
<p>When you are coding, interruptions <strong>really</strong> suck.</p>
<p>You are in the zone, flying high, killing it. And BAM… meeting, standup, <em>insert interruption</em>… Great!</p>
<p>In that context, code reviews can be perceived as another hurdle to productivity.</p>
<p>And frankly I can relate to that.</p>
<h4 id="heading-code-reviews-are-hard">Code reviews are hard.</h4>
<p>Not only do you need to stop what you are currently doing, you also need to immerse yourself into somebody else’s code. It takes <em>a lot</em> of energy just to switch your focus.</p>
<h4 id="heading-code-reviews-are-time-consuming">Code reviews are time consuming.</h4>
<p>According to <a target="_blank" href="https://insights.stackoverflow.com/survey/2019#development-practices">Slack Overflow’s 2019 survey</a>, 56.4% of developers spend 4 hours or more per week performing code reviews. And it can represent up to 20% of a developer’s week!</p>
<h4 id="heading-code-reviews-are-frustrating">Code reviews are frustrating.</h4>
<p>As a submitter, it can be frustrating to get your pull request rejected, to wait hours if not days for a review. As a reviewer, code reviews can feel like an obstacle to a good productive day.</p>
<p>Yes, code reviews can sometimes be hard, time consuming and frustrating.</p>
<p>But they’re also a good way to <strong>share knowledge, prevent bugs, and reinforce your company’s culture</strong> among other things.</p>
<p>What follows is a manifesto for submitters and reviewers to bring back peace of mind into code reviews. ?</p>
<h3 id="heading-a-submitters-manifesto">A Submitter’s Manifesto</h3>
<p>As a submitter, here’s what you can do to increase your chances of getting your pull requests approved in a timely manner.</p>
<h4 id="heading-submit-when-youre-done">Submit when you’re done.</h4>
<p>It sounds obvious, I know. But the thing is — most of the time if the machine doesn’t work, it’s not because it’s broken… it’s because it’s not plugged in!</p>
<p>Very small details can make a big difference on how your work is perceived. And you don’t want your colleagues to feel they are investing time and effort into reviewing work in progress code.</p>
<blockquote>
<p>Me: “It was just a missing !”</p>
<p>You: “Yeah I know, but the whole thing didn’t work and it took me 20 minutes to spot it.”</p>
</blockquote>
<p>So here’s what you can do:</p>
<ul>
<li><strong>Self-test your code.</strong> Include WIP in title or label if you’re not done yet.</li>
<li><strong>Self-review your code.</strong> Use the diff report of your code editor or versioning tool to catch mistakes.</li>
<li><strong>Make sure the tests of your CI are green</strong> before assigning a reviewer, this will save them time.</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5O1kil0Dxt4qNqUrwFEx6sfPRoyjWHqdD7df" alt="Image" width="400" height="300" loading="lazy">
_Don’t be this guy, obviously ? (G[iphy)](https://giphy.com/" rel="noopener" target="<em>blank" title=")</em></p>
<h4 id="heading-make-smaller-pull-requests">Make smaller pull requests</h4>
<p>I get it, it’s a big, important and complex feature and you might be tempted to submit a long pull request. Yet, most of the time, you are better off submitting smaller pull requests.</p>
<p>Code reviews take energy. Big code reviews even more. Don’t impose on your team a <strong>developer vs food</strong> challenge every time they review your code.</p>
<p>Be nice, cut it in smaller chunks. You are also doing yourself a favor:</p>
<ul>
<li><strong>You’ll get more qualitative feedback.</strong> The longer a pull requests the fewer qualitative feedback per line of code you’ll receive. Keep your pull request small (not too small either) and you’ll increase your chances of getting great feedback on it.</li>
<li><strong>You’ll get them approved faster.</strong> It’s a win-win, by breaking down your work into smaller pull requests, you increase your chances of getting them approved faster.</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/irUe6ZKsZwrWHJwrIqGsymee1oo2cq0mMEBs" alt="Image" width="622" height="340" loading="lazy">
<em>LGTM ?</em></p>
<p><em>For the nerds out there, here’s a <a target="_blank" href="https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/">study</a> conducted on a Cisco programming team. It shows that after 400 LoC the ability to find defects diminishes pretty dramatically.</em> ?</p>
<p>The next principle helps with keeping pull requests size under control.</p>
<h4 id="heading-narrow-the-scope">Narrow the scope</h4>
<p>The scope of your pull request should be <strong>simple, unique and well-defined.</strong> That might be a feature, a user-story or a bug fix.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/hVle2Ce9EvgyfDMvplMuSbg3FpXTF9CN55-j" alt="Image" width="800" height="253" loading="lazy">
<em>Making the world a better place, one LoC at a time ?</em></p>
<p>One way to think about it is that reviewers have a <strong>limited number of “attention credits”</strong> (like everybody). Every time they focus on something, they use 1 credit. What happens when they have 0 left?</p>
<blockquote>
<p>LGTM ?</p>
</blockquote>
<p>Do what you can to reduce the noise around your work. Be mindful of the reviewer’s attention span.</p>
<p>For instance, <strong>avoid void changes</strong> (like skipping lines). They don’t add any value and complicate the code review.</p>
<p>Similarly, if your pull request changes the <em>behavior</em>, don’t include changes to <em>formatting</em>. Conversely, if your pull request changes <em>formatting</em>, don’t include changes that affect the <em>behavior</em>. They might be overlooked by the reviewer.</p>
<h4 id="heading-give-context">Give context</h4>
<p>Think about your pull request as documentation for new comers. Guide the reader with context.</p>
<p>Start with a <strong>self-explanatory title.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/-rZMLs8GynJOJMIB2C1ZTf1sa22RdiccZaw2" alt="Image" width="800" height="203" loading="lazy">
<em>Good title taken from the xg2xg repo ?</em></p>
<p>Then<strong>, write a clear description</strong> to explain what you are doing and why are you doing it. What is the purpose of this pull request? Why is this change necessary? How did you approach this problem?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/QfB-BL9MLi1SnpFMByRDtEoGcLsnhYqAbtUZ" alt="Image" width="800" height="250" loading="lazy">
<em>Good example of explaining why the change is necessary taken from react repo</em></p>
<p>The description is also is great place to <strong>point out unresolved issues and open questions.</strong> Reviewers might have suggestions to unblock you.</p>
<p>Are you working on a visible part of the product? <strong>Screenshots</strong> can help get your point across faster.</p>
<ul>
<li>Show before/after differences.</li>
<li>Use colored arrows.</li>
<li>Add screen recordings if you feel like it :)</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/BMOl9N0I3lUy6RFHW6koF-AHvUaS3zj8ZJzz" alt="Image" width="800" height="772" loading="lazy">
<em>From react repository</em></p>
<p>Finally, write <strong>information signs</strong> along the way to guide the reviewer through your reasoning.</p>
<p>Keep a clean commit history to make it easier for the reviewer to follow your step. Use comments to point out alternatives you explored.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/parB1wMVMrNCIoUjqixRqCHHJ08HMuE2FEb8" alt="Image" width="442" height="185" loading="lazy">
<em>Good comment example from Lodash</em></p>
<h4 id="heading-welcome-feedback">Welcome feedback ?</h4>
<p>Rejection hurts.</p>
<p>Truth be told, <strong>code rejection hurts even more.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Hw2grLkrNu8rHBcUJxqHt9v71eUAPRVwiBnn" alt="Image" width="776" height="167" loading="lazy">
<em>I’m seeing this a lot!</em></p>
<p>It’s alright. Don’t take it personally.</p>
<p>Comments and suggestions are an opportunity to learn and become a better software engineer ?</p>
<h3 id="heading-a-reviewers-manifesto">A Reviewer’s Manifesto</h3>
<p>Congrats on making it this far! Now let’s look at a few principles that might help you become a better reviewer ?</p>
<h4 id="heading-adopt-the-right-mindset">Adopt the right mindset</h4>
<p>There is no scenario where a team can benefit from a reviewer being mean or patronising. <strong>Be</strong> <strong>kind</strong>. Period.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/xLy0yeaSYmd9HAUIDvcN892VA7ehvPvD4b5p" alt="Image" width="544" height="291" loading="lazy">
_What are you trying to say my friend? ([Giphy](https://giphy.com/" rel="noopener" target="<em>blank" title="))</em></p>
<p>Want to make code reviews more exciting?</p>
<p>Look for something you can <strong>learn</strong> from this review. A new library, a new method, a new concept, a simpler way to do things. What piece of knowledge will you extract from it?</p>
<p>If you are the more experienced developer, is there something you can <strong>share</strong>? How can you use this review to transfer knowledge to the submitter? How can you help them become a better software engineer?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CA98J-KCq3p77rFiVmv4W5ojoQnUnBEvgNOn" alt="Image" width="669" height="425" loading="lazy">
<em>Thanks for the tip mate! ?</em></p>
<h3 id="heading-how-to-actually-do-a-code-review">How to actually do a code review</h3>
<h4 id="heading-what-to-review"><strong>What to review</strong></h4>
<p>What am I even supposed to look for? Without clear guidance on what and how to review, it’s easy to get lost. Here is what you can do.</p>
<p>First off, <strong>check the purpose</strong>. Is this code accomplishing what it is meant to do? Are there parts of the new code that are not clear to you? Ask clarifying questions. The code is easily testable? Test it. There’s no need to go beyond if this square is not checked.</p>
<p>Ok now that the code works, time to focus on the <strong>implementation</strong>.</p>
<p>Think about how you would have approached this problem. Would you have done it differently? Is there potential for refactoring or abstraction? Is this re-inventing the wheel? Is this using standard code patterns?</p>
<h4 id="heading-what-to-not-review"><strong>What to not review</strong></h4>
<p>Because a piece of code has room for improvement, it doesn’t always mean it needs to be improved.</p>
<p>At the end of the day, code reviews are a tradeoff between <strong>quality</strong> and <strong>velocity</strong> and depending on the scope and stage of the project it might make sense to let a few things behind.</p>
<p>Similarly, you shouldn’t be doing things that can be automated. Let your favorite linter hunt for the missing semicolons and extra indentation. No need for an endless debate on tabs vs spaces.</p>
<p>Finally, don’t increase the scope of the pull request. If you think of new things that need to be done, create a new pull request /task for that matter.</p>
<h4 id="heading-review-in-a-timely-manner">Review in a timely manner</h4>
<p>There are at least 3 good reasons to review pull requests in <strong>hours rather than days.</strong></p>
<ul>
<li>The submitter can move to the next task quicker</li>
<li>It reduces context switching cost</li>
<li>It reduces the risk of merge conflicts between branches.</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XVktldbIDiDVoWG2GCGSIo4ppuEMv49qFU5m" alt="Image" width="800" height="53" loading="lazy">
<em>Opened 6 years ago. Be right back ?</em></p>
<p><strong>Disclaimer:</strong> I just released <a target="_blank" href="https://www.gitrise.com/">GitRise</a>, a tool that helps teams using GitHub &amp; Slack review pull requests faster. I do think it can help with this one :)</p>
<h3 id="heading-how-to-give-feedback-in-a-code-review">How to give feedback in a code review?</h3>
<p>When giving a feedback, the form matters as much as the substance.</p>
<p>Did you know that in written communication, <strong>neutral content looks more negative than it actually is?</strong> Beware of this bias and include emojis when needed to get the tone right in your comments.</p>
<p>Also, most of the time, even if you are pretty sure that there is a better way to do something, you are better off <strong>asking a question rather than requesting a change</strong>. Plus, questions sound less aggressive.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/YDgB2aLyBwOvo21kVLfvYdlKdlTioV1UUP4a" alt="Image" width="799" height="517" loading="lazy">
<em>Example from ember.js repo</em></p>
<p><strong>Finally, reward when things are done right.</strong> Code reviews are also a great place to give kudos to colleagues for doing a good job. Be creative and fun :)</p>
<p>? Congrats on reaching the end of this blog post!</p>
<p>? Thanks a lot for reading and let me know if you have any comments!</p>
<p>? I <strong>just released G<a target="_blank" href="https://www.gitrise.com/">itRise,</a> a tool that creates pull requests reminders for teams using Slack &amp; GitHub. G</strong>ive it a try if you want. Looking forward to your feedback.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
