Tower Blog https://www.git-tower.com/blog Tue, 29 Jul 2025 00:00:00 +0000 Tower Blog - About Web and Software Development, Marketing and Design Git Branching Explained: Base, Topic, and Parent Branches https://www.git-tower.com/blog/base-topic-parent-branches https://www.git-tower.com/blog/base-topic-parent-branches Tue, 29 Jul 2025 00:00:00 +0000 How do you integrate new features without breaking existing functionality? How do multiple developers work concurrently without conflicts? The answer lies in mastering Git's powerful branching capabilities.

Within Git's powerful arsenal, branches are its absolute superpower. They let you, and your team, work on new ideas, fix bugs, and experiment without causing chaos in your main codebase.

In this post, we'll take a deep dive into core Git branching concepts, showcasing why they are absolutely indispensable for stress-free software development.

Let's jump right in by first identifying and distinguishing the key branch types, so you can clearly understand their role and value for any development team:

  1. Base Branches
  2. Topic Branches
  3. Parent Branches

1. The Foundation: Base Branches

Imagine your project's main development path as the sturdy trunk of a tree, or the main highway in a bustling city. In Git, this is what we call a base branch.

A base branch is a long-lived, stable branch that represents the primary line of development for your project. You'll most commonly encounter branches named main (the modern default, replacing the older master) or develop. Think of it as the source of truth – the code that is either currently deployed to production, or is always in a deployable state.

You can have multiple base branches: a typical example is a development branch where work is done and then at some point merged into main, representing your production state that can be deployed.

In a nutshell: The "Base Branch" is the long-lived, stable branch (e.g., main, develop) from which new features or fixes originate. It's the "source of truth" for the project's current state.

The base branch serves as your project's unwavering foundation. It provides a consistent and reliable reference point for everyone on the team, ensuring that there's always a known good version of the code. This stability is crucial, as you don't want experimental or unfinished features breaking what's already working.

As the main line of work lives in your base branches, they serve as essential reference points for many functionalities that determine whether work has been integrated and whether it is safe to delete a topic branch. When using commands like git branch --merged <BRANCH> or git branch --no-merged <BRANCH>, it is important to run these for every base branch to gain an overview of which branches have been merged upstream and which have not.

In an upcoming version of Tower, this information will be used to automatically identify branches that have been merged.

2. Feature Focus: Topic Branches

Now, let's say you're building a new feature, such as a user authentication system, or maybe fixing a tricky bug. You definitely don't want to mess with the stable base branch while you're experimenting!

This is where topic branches come into play.

A topic branch is a short-lived branch that you create to work on a specific feature, bug fix, or experiment. When you type something like git checkout -b new-auth-feature main, you're essentially saying, "Hey Git, create a new branch called new-auth-feature based on the current state of main, and then switch me over to it!"

The lifecycle of a topic branch is straightforward: you create it, do your work, test it, and once it's complete and reviewed, you merge it back into your base branch. After the merge, the topic branch is typically deleted, keeping your repository tidy.

In a nutshell: If main is the main road, a topic branch is a temporary detour you take to work on something specific. Once you're done, you merge your changes back onto the main road.

Topic branches allow you to work on your changes in a completely isolated environment, which is clearly the main advantage of working this way. If your new feature introduces unexpected bugs or doesn't pan out as planned, it's contained within the topic branch. You can fix it there or simply discard the branch without ever affecting the stable main branch.

Topic branches also provide a sensible way to collaborate. Multiple developers can work on different features simultaneously, creating their own topic branches so they don't step on each other's toes. This approach also has its advantages when it's time to review the code before merging, often through creating pull requests. Your teammates can review your changes, offer feedback, and approve them before they become part of the main codebase.

As a bonus, this approach contributes to a clean project history, as your base branch maintains a clear, understandable, and linear history of integrated features rather than a jumbled mess of individual commits.

3. The Lineage: Parent Branches

Every branch has a history, and part of that history is its parent branch. Simply put, the parent branch is the branch from which another branch was created. It's the immediate ancestor, defining the starting point and initial state of the new branch.

Most often, when you create a topic branch like feature/shopping-cart, its parent branch will be your base branch, main or develop. The new feature/shopping-cart branch inherits all the commits and files that were present in main at the moment it was created.

In a nutshell: The parent branch is the "origin" of a child branch. It's the branch whose history the new branch inherits at the moment of its creation.

This relationship determines which changes will be exclusive to your topic branch compared to its parent branch. With Tower 14 for Mac, the parent branch is selected by default when using the "Compare" view, allowing you to see only the unique commits introduced by this feature branch.

Tower 14 — Branch Comparison
Tower 14 — Branch Comparison


If you have multiple base branches, a base branch can also have another base branch as a parent. Consider our example from above (in the "Base Branches" section): your develop’s branch parent would be main, as work ultimately always flows upwards to your main branch. The other way around, if main would receive changes from e.g. hotfix branches, develop would need those changes from main in order to stay in sync.

Tower 14 makes it easy to stay uptodate with the new "Update Branch" action.

Tower 14 —
Tower 14 — "Update Branch" Action


The parent branch is usually the branch that your topic branch will be merged back into, unless you are using stacked branches (see below). In that case, the stacked branch will ultimately be merged back into the trunk branch after all stacked parents have been merged.

The Stacked Branches Workflow

While a new branch typically sprouts directly from your base branch, sometimes your work is so extensive, or involves multiple interdependent logical changes, that it benefits from a more layered approach.

This is where stacked branches, also known as "stacked pull requests", come into play.

These are a series of dependent topic branches. Instead of each new branch directly diverging from the base, they form a chain of dependencies.

It looks something like this:

The Stacked Branches Workflow
The Stacked Branches Workflow


In this scenario:

  • refactor-payment-gateway's parent is main.
  • implement-stripe-integration's parent is refactor-payment-gateway.
  • add-subscription-plans's parent is implement-stripe-integration.

Each branch in the stack represents a distinct, logically isolated chunk of work, but they are built upon, and thus dependent on, the changes introduced in the "parent" branch below them in the stack.

Stacked Branches: Pros and Cons

Let's start with the good: Stacked Branches are a great solution when you're working on large features that can be overwhelming to review. By breaking them into a stack, each pull request (PR) for a branch in the stack is smaller and easier to understand, speeding up code reviews.

This allows for faster, uninterrupted development since you don't have to wait for the first part of a large feature to be reviewed and merged before starting work on related parts. This also enables you to ship parts of a larger feature incrementally, delivering value sooner.

Stacked branches can present some challenges, most notably the need for frequent rebasing to keep them up to date with the base branch. For this reason, additional tools are often recommended.

Good news — Tower not only supports Stacked Branches but can do the restacking automatically for you! This was introduced in Tower 12 for Mac and Tower 8 for Windows.

Restacking in Tower for Mac
Restacking in Tower for Mac


Specialized tools like Graphite can simplify the management of stacked pull requests. Tower is the only Git client with Graphite support, allowing for Stacked PR management without the need of using the Graphite CLI or the browser.

You can learn all about this integration in the 5-minute video below:

Best Practices for Branching

To maximize the benefits of branching, we would like to share some advice with you, along with some helpful Tower tips!

  • Keep Topic Branches small: Focus each topic branch on a single, logical change. Smaller branches are easier to review and manage.

  • Descriptive naming is recommended: Make an effort to use meaningful names for your branches, such as feature/user-profile-edits, bugfix/login-form-validation, or hotfix/critical-api-issue.

  • Merge or Rebase frequently: Regularly update your topic branch with the latest changes from its parent (usually the base branch) to minimize complex merge conflicts later on.

With Tower, merging is as simply as dragging and dropping!

Merging a branch in Tower with Drag and Drop


Keeping topic branches up to date has become even easier with the release of Tower 14 for Mac. By setting up parent/child relationships, Tower will notify you whenever your branch needs updating; When this occurs, you can simply click the "Update Branch" action instead of manually merging or rebasing branches.

Tower 14 – Track Parent Branch
Tower 14 – Track Parent Branch


  • Always use pull requests for code review and integration: This ensures a thorough review process before changes hit the base branch.

With Tower, you can create a pull request by simply dragging and dropping the desired branch onto the "Pull Requests" workspace view.

Creating a pull request in Tower with Drag and Drop


And if you are an adopter of the Stacked Branches workflow, remember to always restack to keep your branches in sync by restacking often.

Tower 13 for Mac — Restack Branch Dialog
Tower 13 for Mac — Restack Branch Dialog


  • Delete branches after merging: Once a topic branch is merged into your base branch, delete it from your local and remote repositories to keep things clean.

In Tower's "Branches Review" view, you can filter by "Fully Merged" to pinpoint the branches that can be removed without hesitation.

Cleaning up fully merged branches in Tower

Final Words

By embracing the foundational stability of your Base Branch, the focused isolation of Topic Branches, and the logical structure provided by Parent Branches (even in complex stacked scenarios), you are setting yourself and your team up for safe experimentation, parallel feature development, and clear code reviews.

Follow these guidelines and our branching best practices to enjoy a development workflow that is more efficient, less stressful, and ultimately more productive.

For more Git tips and tricks, don't forget to sign up for our newsletter below and follow Tower on Twitter / X and LinkedIn! ✌️

]]>
Tower 14 for Mac (Beta) — Custom Git Workflows https://www.git-tower.com/blog/tower-mac-14 https://www.git-tower.com/blog/tower-mac-14 Tue, 29 Jul 2025 00:00:00 +0000 Tower 14 for Mac is now in beta! This update allows you to create custom Git workflows, enabling you to define and enforce the exact workflow that meets your project's needs.

We have spoken with many teams and learned that most struggle to develop their own ideal Git workflows. As a result, they often end up adapting generic solutions or creating systems that are difficult for everyone to follow.

If that resonates with you, you will definitely love this release! Tower 14 for Mac puts you in the driver's seat, allowing you to define trunk, base, and topic branches, as well as set merge strategies and various other options.

Think of this as creating your own system — such as git-flow — but with limitless possibilities! 😎

☝️ Tower 14 is currently in Beta. To try it out, simply change the Release Channel to "Beta" under Settings > Updates in the Tower for Mac application.

We're incredibly excited about the power and flexibility that Custom Git Workflows bring to Tower for Mac. As this feature is currently in beta, we invite you to join us in shaping its future by letting us know what you think!

All right, let's take a look at what's new – but first, let's recap why you should consider using a Git workflow if you don't have one already.

Why Workflows Matter

It is important to standardize your branching and merging practices so that you can create a predictable development environment. We feel this is key for a productive, enjoyable experience with Git, especially when collaborating with teams!

This standardization and predictability offer many advantages.

  1. Every team member can easily understand the repository's state and the purpose of each branch if you use clear naming conventions and well-defined merge behaviors.
  2. New colleagues can quickly grasp the project's specific Git conventions, leading to quicker onboarding.
  3. The entire team will become less prone to errors.

Workflows can (and should!) be automated, making this process even more beneficial to everyone — and this is exactly where Tower 14 comes in.

Setting Up a Custom Git Workflow

The heart of Custom Git Workflows lies in its flexibility. You can create a workflow tailored to your project, team size, and development methodology. They can be as simple or complex as you'd like!

The magic begins by clicking on the "Workflows" icon, now conveniently located on the left-hand side next to the "Services" and "Bookmarks" views.

Tower 14 –
Tower 14 – "Workflows" icon in the Toolbar


Here, you can set your preferred workflow by choosing from the following options:

  • Predefined workflows, such as git-flow or GitHub/GitLab Flow.
  • Other workflows like Graphite or GitFlow CLI.
  • The option to create any custom Git workflow you can imagine from scratch.

If your project already has a workflow in place, Tower will attempt to auto-detect it based on the existing branches.

Tower 14 – Select your Workflow
Tower 14 – Select your Workflow


To understand the power of this feature, let's explore an existing workflow — we will use git-flow— and break down the extensive customization options available in Tower Workflows.

Tower 14 — Branch Workflow Configuration
Tower 14 — Branch Workflow Configuration


Look at all those options! Let's explore what they can do.

The first step is to define your core branches, i.e., your "trunk" (e.g., main, master) and "base" (e.g., develop, dev) branches so that you can establish the foundational structure of your repository.

☝️ If you want to learn more about "trunk", "base", and "topic" branches, we recommend reading this article.

Afterwards, you should define your "topic" branch types (e.g., feature, hotfix, release). For each topic branch type, you can set specific branch prefixes (e.g., feature/, hotfix/). This clarifies intent and ensures consistency across your team and can be used for automated checks and organization.

In the example below, we've added bugfix to our Workflow, which is not part of git-flow by default — a prime example of the customizability of this feature.

Tower 14 – Topic Branch Configuration
Tower 14 – Topic Branch Configuration


Next, you can take full control of how changes flow through your branches. You can now define distinct downstream merge strategies (merging the parent into your topic branch to keep it up to date) and upstream merge strategies (merging a branch into its parent to finalize topic branches).

Whether you prefer merge, rebase, or squash, Tower 14 lets you dictate the exact behavior for each merge scenario.

Tower 14 — Merge Strategy Configuration
Tower 14 — Merge Strategy Configuration


When merging upstream, you can also create a tag, which can be useful for releases or significant milestones. This makes sure critical points in your project's history are always marked.

Finally, you have the option to create a merge commit when integrating branches, ensuring a complete and traceable record of all integrations. For those who prefer a cleaner, linear history, you can opt out.

Tower 14 – Configuring Merge Commit and Tag Creation
Tower 14 – Configuring Merge Commit and Tag Creation

Starting and Finishing a Feature/Hotfix/…

Once your workflow is configured, you can easily get started with your work by clicking the "Workflows" button and choosing the appropriate option.

Tower 14 –
Tower 14 – "Start Feature"


Once the task is complete, you can either click the "Workflows" button again to finish the feature, or access the branch's context menu by right-clicking the mouse.

Tower 14 –
Tower 14 – "Finish Feature" in the Context Menu

Updating Branches

While you are working on a new feature, it's normal for the parent branch to receive new commits from other team members. To minimize the chance of encountering merge conflicts, you should integrate those changes frequently.

We have good news here: this is very easy when using Tower ✌️

Since Tower establishes a parent/child relationship between branches, you will see a yellow banner reminding you that you should update your child branches since there have been updates to the parent branch.

This feature is extremely useful for smoothly integrating your changes when you finish working on a feature or bug fix, so we recommend that you update your child branches often!

Tower 14 –
Tower 14 – "Update Branch" notification


In the update process, Tower will always inform you if there are any merge conflicts that need to be resolved.

Tower 14 –
Tower 14 – "Update Branch" dialog


TIP: Don't forget to establish dependencies between branches so that child branches receive updates from their parent branches when changes occur. You can right-click any branch at any time and set a different "Upstream" or "Parent Branch" to track.

Tower 14 – Track Parent Branch
Tower 14 – Track Parent Branch

Other Improvements

As usual, we have also taken the time to make some other enhancements behind the scenes.

Here is the list of improvements and bugs that we have worked on:

  • You can now use Stacked Branches with any Tower Workflow without the need to choose it as dedicated workflow.

We hope you enjoy this release! Happy committing! 😊

Not a Tower user yet? Download our 30-day free trial and experience a better way to work with Git!




PS: Did you know? Tower Pro is now free for students as well as teachers and educational institutions!

]]>
Tower 9.1 for Windows — Gitea and Gitmoji Support https://www.git-tower.com/blog/tower-windows-91 https://www.git-tower.com/blog/tower-windows-91 Tue, 01 Jul 2025 00:00:00 +0000 With the release of Tower 9.1 for Windows, we're bringing the power of Gitea directly to our Git client! This means that you can now add your Gitea accounts and manage your precious repositories and pull requests without ever leaving Tower 😊

Gitea isn't the only star of the show; this release also introduces support for Gitmoji, allowing you to create more meaningful and expressive commits!

In an age where cloud services reign supreme, the idea of hosting your own code might seem a bit old-school. But for many, privacy, control, and performance are paramount. This is where self-hosted Git solutions truly shine, offering a robust alternative to public cloud providers. And among these, Gitea has emerged as a fantastic candidate.

Gitea is a lightweight, open-source, self-hosted Git service that provides everything you need for Git hosting, code review, team collaboration, and more, all within your own infrastructure.

This means complete control over your data, enhanced security, and, often, better performance tailored to your specific needs. It's also very popular among teams that simply want to avoid vendor lock-in.

☝️ If you're new to Gitea, we have prepared a quick tutorial to help you get started with Gitea on a VPS 😎

All right, let's see how you can add Gitea as a remote service to Tower and get started! If you prefer, you can also watch the 5-minute video tour below:

Adding a Gitea Account to Tower

Getting your Gitea account set up in Tower is a breeze and it works like adding any other remote service, like GitHub, BitBucket, or GitLab.

To add a new Gitea service account, simply follow these steps:

  1. Navigate to the "Remote Services" view by clicking the cloud icon in the toolbar, selecting "View > Show Services," or pressing Alt + S.
Tower 9.1 for Windows —
Tower — "Services" in the Toolbar


  1. Click on the "Gitea" or "Gitea Self-Hosted" option in the Service Accounts list, or click the "+" button in the bottom-left corner to add a new Gitea account.
Tower 9.1 for Windows —
Tower — "Gitea" and "Gitea Self-Hosted" options


  1. Tower will then prompt you for your Gitea instance URL and your credentials. Enter the full URL of your Gitea server (if self-hosted) and then provide your username and password (or better yet, a personal access token for more secure authentication).
Tower 9.1 for Windows — Add Gitea Account
Tower — Add Gitea Account


  1. Once you've entered your details, click "Add Account". Tower will verify your credentials; if successful, your Gitea account will appear in your Services list.
Tower 9.1 for Windows — Gitea Repositories
Tower — Gitea Repositories


And just like that, you're connected! All your Gitea repositories will now be accessible, ready for you to clone, fetch, and manage! 🎉

Inspecting Gitea Pull Requests in Tower

One of the most powerful features of Git is the ability to collaborate through pull requests. Gitea enables you to easily create pull requests directly in the browser, as shown below.

Creating a Pull Request in Gitea
Creating a Pull Request in Gitea


However, Tower allows you to seamlessly manage your Gitea pull requests, making code review and collaboration even more efficient — no need to open browser windows!

Once your Gitea account is added (as described in the previous chapter), open any repository and navigate to the "Pull Requests" section in Tower's sidebar, found under the "Workspace" heading.

Tower will display a list of all open pull requests for that repository. You'll see key information such as the pull request title, author, and status.

Tower — Gitea Pull Requests
Tower — Gitea Pull Requests


Click on any pull request in the list to open its detailed view. You will find 3 tabs:

  1. Conversation: View comments from your team members and reply.
  2. Commits: Browse the commit history and inspect individual file changes.
  3. Changeset: View the full diff of changes.

At the bottom, you will also have the option to check out, close, or merge the pull request, assuming you have the necessary permissions.

This functionality eliminates the constant context switching between your Git client and the Gitea web interface — it's all about staying in the flow 😎

Gitmoji Support

Gitmoji is an open-source project that aims to standardize the use of emojis in commit messages. You can learn more about it in this blog post.

While you can manually enter the necessary emojis when creating a commit, the recommended method is to use the Gitmoji CLI tool or… the latest release of Tower for Windows! 😎

Let's see it in action.

Crafting a Commit with Gitmoji

Tower supports Gitmoji without the need to install any additional tools. This feature was first introduced in Tower 10.5 for Mac and is now also available on Tower for Windows.

To include emojis in your commit message, just type :: in the "Commit Subject" field. A list of emojis will show up, along with descriptions of their meanings. You can also have a look at the complete list of emojis available here.

Tower 9.1 for Windows — Add Gitmoji
Tower 9.1 for Windows — Add Gitmoji


Gitmoji is also available in our Commit Composing tools, which you can access by simply typing /.

Tower 9.1 for Windows — Commit Composing with Gitmoji
Tower 9.1 for Windows — Commit Composing with Gitmoji


That's it! As you can see, adding the right emoji to your commit messages is quite simple.

Tower will also display the emojis in any "History" view, as shown below.

Tower 9.1 for Windows — History View with Gitmoji
Tower 9.1 for Windows — History View with Gitmoji

Other Improvements

As is tradition, we've also addressed some other small improvements and bug fixes, such as:

  • LFS: Pulling LFS repositories now works as expected.
  • Sidebar: Remote names are now accurately updated after renaming.
  • Network Paths: Fixed a potential crash when handling network paths.
  • Services: Enhanced logic for matching repositories to their configured services.
  • UI: Increased separator visibility in Dark Mode and improved visualization of parent-child branch relationships.
  • Portable Git: Updated to version 2.50.0 for improved compatibility and performance and upgraded the zip utility to support the latest compression formats.
  • Shortcuts: Reassigned the Ctrl + Shift + Backspace shortcut to the "Reset" action and removed it from "Discard All Changes", ensuring more intuitive shortcut behavior.
  • Stacked branches: Fixed an issue where the restack context menu item was incorrectly enabled, as well as an issue where, under certain conditions, the restack dialog validation could run indefinitely.

For the complete changelog, please have a look at the Release Notes.

We hope you enjoy our latest Windows release. Happy committing! 😊

New to Tower? Download our 30-day free trial and discover a more efficient way to work with Git!




PS: Did you know? Tower Pro is now free for students as well as teachers and educational institutions!

]]>
How to Install Gitea (with SQLite3 and HTTPS!) on a VPS https://www.git-tower.com/blog/how-to-install-gitea https://www.git-tower.com/blog/how-to-install-gitea Tue, 24 Jun 2025 00:00:00 +0000 Setting up your own Gitea instance on a VPS might sound daunting, but trust me, it's more straightforward than you think! By following this guide, you'll have your private Git server up and running in no time.

This is quite a fun project that offers significant benefits! By the end of this tutorial, you will have unparalleled control over your source code, your data, and your team's collaboration workflow.

Here is the plan for today:

  • Install Gitea on a VPS with a fresh Ubuntu 24.04 installation
  • Configure Gitea with SQLite 3
  • Set up HTTPS with Nginx and Let's Encrypt

So, grab your terminal, pour yourself a cup of coffee, and let's get started on bringing your Git hosting in-house.

📣 We are celebrating the Tower 9.1 for Windows release, which brings full Gitea support. This means that you can now manage your repositories and pull requests directly in our Git client!

Preparing Your VPS: The Groundwork

Before we install Gitea, we need to ensure our VPS is ready. For this tutorial, we'll assume you're using a fresh Ubuntu 24.04 LTS instance, which is a popular and stable choice.

1. Connect to Your VPS via SSH

First things first: open your terminal and connect to your VPS. Replace your_username and your_vps_ip with your actual login details:

ssh your_username@your_vps_ip

If this is your first time connecting, you might be prompted to confirm the host's authenticity. Type yes and press Enter.

2. Update Your System

It's always a good practice to update your package lists and upgrade any existing packages to their latest versions:

sudo apt update && sudo apt upgrade -y

3. Install Required Dependencies

Gitea requires Git, a database, and a few other packages. We'll use SQLite3 for simplicity in this tutorial, but for larger deployments, you might consider PostgreSQL or MySQL.

sudo apt install git sqlite3 -y

4. Create a Git User for Gitea

Gitea runs best under its own dedicated user. This enhances security by isolating the Gitea process.

adduser \
   --system \
   --shell /bin/bash \
   --gecos 'Git Version Control' \
   --group \
   --disabled-password \
   --home /home/git \
   git

This command creates a new system user named git with a home directory at /home/git.

Installing Gitea

Now that the groundwork is laid, let's get Gitea onto your server! We'll download the official binary, which is the easiest way to get up and running.

1. Download the Gitea Binary

First, please check the official Gitea documentation for the latest stable release. Look for the Linux AMD64 static binary. As of writing, the latest stable version is 1.23.8.

wget -O gitea https://dl.gitea.com/gitea/1.23.8/gitea-1.23.8-linux-amd64

Now, we will make the binary executable and copy it to a more appropriate folder: /usr/local/bin/gitea

chmod +x gitea
cp gitea /usr/local/bin/gitea

2. Create Necessary Directories

Gitea needs specific directories for its configuration, logs, and repositories.

mkdir -p /var/lib/gitea/{custom,data,log}
chown -R git:git /var/lib/gitea/
chmod -R 750 /var/lib/gitea/
mkdir /etc/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea

⚠️ Please note that /etc/gitea is temporarily set with write permissions so that the web installer can write the configuration file. After the installation is finished, we should change these permissions to read-only using:

chmod 750 /etc/gitea
chmod 640 /etc/gitea/app.ini

3. Create a Systemd Service for Gitea

Running Gitea as a systemd service ensures it starts automatically on boot and can be managed easily.

Create a new service file:

sudo nano /etc/systemd/system/gitea.service

Paste the following content into the file. Pay close attention to the WorkingDirectory and ExecStart paths:

[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target network.target

[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea

[Install]
WantedBy=multi-user.target

Save and exit (Ctrl + X, Y, Enter).

4.. Enable and Start the Gitea Service

sudo systemctl enable gitea
sudo systemctl start gitea
sudo systemctl status gitea

You should see output indicating that the Gitea service is active (running). If not, check the logs with journalctl -u gitea.

Initial Gitea Configuration (Web Interface)

Gitea is now running! You can access its web installer to complete the setup.

1. Access the Web Installer

By default, Gitea listens on port 3000. Open your web browser and navigate to http://your_vps_ip:3000.

You'll be greeted by the Gitea installation page. Feel free to review each field, but there's only one key setting that you should change: the Database type.

  • Database Type: SQLite3

Click "Install Gitea". This process will create the app.ini configuration file in /etc/gitea.

After the installation, it's time to register your first user, which will be the administrator account. Simply click on "Register Now" and enter a username, email address, and password.

Gitea – User Registration
Gitea – User Registration


Success! You should now have access to the Gitea dashboard! 🎉

Gitea – Dashboard
Gitea – Dashboard

Setting Up HTTPS with Nginx and Let's Encrypt

Having Gitea running is great, but accessing it via http://your_vps_ip:3000 isn't very secure or user-friendly. We want to access it via https://gitea.mywebsite.com. This requires a web server (Nginx) acting as a reverse proxy and an SSL certificate (from Let's Encrypt).

1. Point Your Domain to Your VPS

Before proceeding, make sure your domain's DNS records are set up. Create an A record for gitea.mywebsite.com that points to your VPS's public IP address. DNS changes can take some time to propagate.

2. Install Nginx

Nginx will be our web server that handles incoming requests on port 80 and 443 and forwards them to Gitea running on port 3000.

sudo apt install nginx -y

3. Configure Nginx as a Reverse Proxy

Create a new Nginx configuration file for your Gitea site:

sudo nano /etc/nginx/sites-available/gitea.conf

Paste the following configuration. Replace gitea.mywebsite.com with your actual domain.

server {
    listen 80;
    server_name gitea.mywebsite.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Save and exit.

4. Enable the Nginx Site and Test Configuration

Create a symbolic link to enable the site:

sudo ln -s /etc/nginx/sites-available/gitea.conf /etc/nginx/sites-enabled/

Test your Nginx configuration for syntax errors:

sudo nginx -t

If it reports "syntax is ok" and "test is successful", reload Nginx to apply the changes:

sudo systemctl reload nginx

Now, if you navigate to http://gitea.mywebsite.com (without the :3000 port), you should see your Gitea instance!

5. Install Certbot (for Let's Encrypt SSL)

Time for SSL! Let's install Certbot, a tool that automates obtaining and renewing Let's Encrypt SSL certificates.

sudo apt install certbot python3-certbot-nginx -y

6. Obtain and Install SSL Certificate

Now run this command, once again replacing gitea.mywebsite.com with your own domain.

sudo certbot --nginx -d gitea.selfhostfun.win

Certbot will guide you through the process interactively. It will ask for your email and require you to agree to the terms of service.

Once that is done, Certbot will automatically modify your Nginx configuration to include the SSL certificates and force HTTPS.

7. Update Gitea's Base URL in app.ini

Finally, we need to tell Gitea that it's now accessible via HTTPS. Edit Gitea's main configuration file:

sudo nano /etc/gitea/app.ini

Find the [server] section and change the ROOT_URL to your HTTPS domain:

[server]
PROTOCOL = http
DOMAIN = gitea.mywebsite.com
ROOT_URL = https://gitea.mywebsite.com/
HTTP_PORT = 3000

Note: Keep PROTOCOL = http and HTTP_PORT = 3000 because Nginx is handling the HTTPS part and forwarding to Gitea's internal HTTP port. The ROOT_URL is what Gitea uses for generating links internally.

Save and exit.

8. Restart Gitea to Apply Changes

sudo systemctl restart gitea

All Done!

Congratulations! You should now have your very own Gitea instance running securely on your VPS, accessible via https://gitea.mywebsite.com!

Gitea — Installation Complete with HTTPS
Gitea — Installation Complete with HTTPS


You've taken full control of your Git hosting, providing a private, powerful, and efficient platform for your team's code collaboration. No more relying solely on public cloud services when you have the power to host your code exactly how you want it!

With your Gitea instance up and running, you can now seamlessly integrate it with Tower for Windows 9.1, bringing all the power of your self-hosted Git repositories and pull requests right to your desktop 😎

Tower —
Tower — "Gitea" and "Gitea Self-Hosted" options


We hope you found this post helpful. For more Git tips and tricks, don't forget to sign up for our newsletter below and follow Tower on Twitter / X and LinkedIn! ✌️

]]>
Tower 13 for Mac — Introducing Graphite Support https://www.git-tower.com/blog/tower-mac-13 https://www.git-tower.com/blog/tower-mac-13 Tue, 24 Jun 2025 00:00:00 +0000 Tower 13 is here! If you are a fan of Stacked Pull Requests, "13" is indeed your lucky number! This update introduces seamless Graphite support for all the most popular actions, allowing you to manage your stacked branches and create Pull Requests without ever leaving our Git client.

Our previous major release laid the groundwork for adding popular Git workflows by introducing Branch Dependency capabilities and the "Restack" action — and many Tower users have embraced this new workflow with open arms.

Now, Tower 13 takes full advantage of this foundation to support Graphite tooling, enabling you to integrate changes into your project at a rapid pace.

In this blog post, you will learn more about Graphite and its integration into Tower 13. If you prefer, you can also watch the 5-minute video tour below:

About Graphite

If you're looking to improve the Pull Request approval process in your organization and haven't heard about Graphite yet, we think you're missing out!

Graphite provides a stack-based workflow that enables developers to work on multiple features simultaneously by stacking changes on top of each other. This approach is commonly referred to as the Stacked Pull Requests workflow.

The concept is simple: by chaining incremental Pull Requests, there is less code to review, leading to faster code integration and a reduced likelihood of introducing bugs or running into major merge conflicts.

For this approach to be successful, managing branches efficiently is paramount – and that's where Graphite shines! Even if you're the first (or only) person on your team to adopt this workflow, everything will work perfectly right away, so there's absolutely no reason not to give it a try 😉

In addition to effortless branch management, Graphite also provides its own interface for code reviews (check out Diamond — hot off the press!) and works alongside GitHub, enhancing its functionality.

Apart from the Web UI, Graphite also offers:

You can learn more about Graphite in this blog post. We thought it would be nice to integrate these features into a Git client, so we rolled up our sleeves and built just that.

Let's begin the guided tour!

Working with Graphite in Tower 13

To get started, click the "Workflow" button available in the toolbar and pick the new entry: Graphite.dev!

Tower 13 – Enabling the Graphite Workflow


☝️ Please note that you need to have a Graphite.dev account and the Graphite CLI tool installed (version 1.5.3 or higher).

You will then be prompted to define the "Trunk" branch (usually main) and enter your Graphite token (more info here) and the path to the Graphite binary.

We recommend installing the Graphite binary using homebrew, as Tower should automatically detect it. That said, Tower also supports detection via npm (the standard package manager for Node.js), so it should pick it up as well.

Tower 13 — Configure Graphite Workflow
Tower 13 — Configure Graphite Workflow


With everything set up, Tower will automatically load the branch information from Graphite by executing the command that CLI Graphite users recognize as gt state in the background.

You may have noticed that the "Workflow" icon has switched to Graphite. By clicking the button, you will be able to quickly access some of Graphite's most popular commands and open the Graphite dashboard in your browser.

Tower 13 – Graphite Workflow in Toolbar
Tower 13 – Graphite Workflow in Toolbar


All right, this is the perfect time to explore the Graphite commands that you can effortlessly run in Tower!

Working Copy

With the Graphite workflow enabled, the first thing you will notice is that there are new options available in the "Working Copy" view.

We've added a new "Create" action that allows you to instantly create a new branch with the staged changes (the equivalent of gt create in Graphite's CLI tool). This is a good practice within the Graphite workflow, as it is recommended to treat each branch as an atomic changeset containing, at least initially, a single commit.

The "Commit" action functions like the gt modify --commit command in Graphite: it adds a new commit to the currently checked-out branch and automatically restacks if necessary, provided there are no conflicts.

Tower 13 —
Tower 13 — "Working Copy" view

☝️ Tower's "Quick Amend" feature also works with the Graphite workflow. To modify the current branch by amending its commit, hold the Option key () and the "Commit" button will be renamed to "Modify". This is the equivalent of running gt modify in Graphite's CLI tool.

Creating a Stacked Branch

Graphite is all about Stacked Branches, and creating a new one couldn't be easier: just right-click on the "Branches" view in the sidebar to create a new stacked branch.

Tower 13 — Create New Stacked Branch
Tower 13 — Create New Stacked Branch


In the next dialog, you can select its parent branch for easy integration and choose to pin it and/or check it out immediately.

Tower 13 — Create New Stacked Branch Dialog
Tower 13 — Create New Stacked Branch Dialog

Managing Branches

You can also create a new stacked branch by right-clicking on any branch and selecting the preferred option from the context menu.

Additionally, you can perform all other common Graphite operations, such as renaming, merging, squashing, or deleting branches.

Tower 13 – Graphite Commands in Context Menu
Tower 13 – Graphite Commands in Context Menu

Setting the Parent Branch

At any moment, you can change the parent branch of a branch; this works in the same way as you would for Stacked Branches — by accessing the context menu and clicking on "Track Parent Branch."

In Graphite terminology, you may know this as "tracking" (gt track) and "untracking" (gt untrack) a stacked branch.

Tower 13 – Setting the Parent Branch
Tower 13 – Setting the Parent Branch

Restacking

Restacking synchronizes all changes by rebasing each child branch onto its parent branch. Tower will display an icon in the sidebar for the branches that require restacking, and you can easily perform this action by right-clicking the desired branch and selecting "Restack [Branch]".

In the branch's history view, you will also notice a yellow banner informing you that the branch needs restacking.

Tower 13 — Restack Branch
Tower 13 — Restack Branch


In the "Restack Branch" dialog, you will notice a "Restack Full Stack" option. If this option is not active, Tower/Graphite will restack the selected branch and all its parent branches. If the option is selected, the children of the branch will also be restacked (hence the name "full stack").

Tower will notify you of any conflicts that may arise during the restacking operation.

Tower 13 — Restack Branch Dialog
Tower 13 — Restack Branch Dialog

Syncing a Branch

Right-clicking any branch will also give you the option to "sync" it. As the name suggests, this will synchronize all the branches in the stack, similar to running the gt get command.

Tower 13 — Sync Branch Dialog
Tower 13 — Sync Branch Dialog


Tower also provides you with additional options, such as the ability to restack all branches in your repository.

Submitting a Branch (To Create a Pull Request)

You can submit a branch (effectively creating a PR) by right-clicking the branch and choosing the appropriate option from the context menu.

You can access additional options by clicking the drop-down arrow, such as updating only the branches that already have open PRs.

Tower 13 — Submit Branch to Graphite
Tower 13 — Submit Branch to Graphite


All available Pull Requests can be quickly accessed in Tower's "Pull Requests" view, located in the sidebar or by using the shortcut ⌘ + 4.

Tower 13 — Pull Requests
Tower 13 — Pull Requests


This view enables you to inspect, merge, close, comment on, or check out pull requests without the need to open a browser window.

Merge Queue

Graphite offers a Merge Queue feature that prevents semantic merge conflicts by automating the rebase process during merges. This ensures that the trunk branch remains "green", allowing development teams to progress more quickly with fewer disruptions.

In Tower, if merging is possible, the Graphite branch is added to the merge queue. The merge is performed asynchronously, so be sure to manually refresh and sync the branch afterwards to check if it has been merged.

When a Graphite branch is submitted to the merge queue, it is validated remotely to determine if it can be merged. If merging is possible, it is merged; if not, the process fails.

To run this operation, simply right-click the branch and select "Add [BRANCH] to Merge Queue…" from Tower's context menu.

Tower 13 — Graphite's Merge Queue
Tower 13 — Graphite's Merge Queue

Warning Messages

While using Tower, you may inadvertently disrupt Graphite's state by performing certain Git operations, such as a git push, shown below.

Tower will alert you whenever this situation may arise before you continue.

Tower 13 — Warning Message
Tower 13 — Warning Message


These prompts can be enabled and disabled by visiting the "Integration" tab in Tower's Settings.

Tower 13 — Integration Settings
Tower 13 — Integration Settings

Other Improvements

As usual, we have also taken the time to make some other enhancements behind the scenes.

Here is the list of improvements and bugs that we have worked on:

  • Rounded Avatars: Tower now displays rounded avatars for authors and committers.
  • Working Copy: Tower could crash if a user profile referenced an invalid signing key. This has been fixed.
  • History View improvements: Enhanced commit loading performance with signature verification enabled. Fixed issues with scroll position reset and empty list display . Resolved high CPU usage problem caused by GPG key server interactions.

We hope you enjoy this release! Happy stacking! 😊

Not a Tower user yet? Download our 30-day free trial and experience a better way to work with Git!




PS: Did you know? Tower Pro is now free for students as well as teachers and educational institutions!

]]>
Meet Graphite – The AI Developer Productivity Platform https://www.git-tower.com/blog/graphite https://www.git-tower.com/blog/graphite Wed, 30 Apr 2025 00:00:00 +0000 As developers, we love building things. What we don't enjoy as much is waiting: waiting for code reviews, getting blocked on merges, and the general friction that can sometimes slow down the development process.

If this resonates with you, then you'll want to hear about Graphite, a platform designed to tackle these very challenges head-on.

Graphite positions itself as an AI developer productivity platform, aiming to help engineering teams create, review, and merge smaller code changes more efficiently, stay unblocked, and ultimately ship faster.

In this post, let's find out how Graphite can help you accomplish just that.

📣 Tower 13 for Mac, currently in Beta, introduced Graphite support!

Giving Time Back to Your Engineering Team

The folks at Graphite understand a core pain point for many engineering teams: code review can be a significant time sink. In fact, they point out that many engineers spend a day or more each week either reviewing code or stuck waiting for their own reviews to come through. That's a substantial chunk of valuable engineering time!

But Graphite believes it doesn't have to be this way. The team behind Graphite has a strong background, with many founding members hailing from tech giants like Meta and Google. These companies have, in many cases, developed their own internal code review tools to optimize their engineers' workflows. The Graphite team missed the power of these internal systems, particularly the stacked diffs workflow, which they initially leveraged in an internal tool.

The internal tool proved so effective that the team decided to pivot and focus entirely on developing it into the platform we now know as Graphite. Their mission is to bring the power of stacked pull requests – the very workflow that underpins best-in-class internal code review tools like Phabricator and Critique – to every software company.

Diamond – Embracing AI

Beyond just stacked PRs, Graphite also recognized the potential of AI early on, culminating in the release of Diamond (formerly known as Graphite Reviewer).

As a codebase-aware AI code review companion, it provides developers with immediate, actionable feedback on their pull requests, significantly reducing the number of review cycles. While other AI bots hallucinate and create noisy comments, Diamond is calibrated to catch real bugs and deliver smarter, targeted feedback with fewer false positives.

Diamond – Agentic AI Code Review
Diamond – Agentic AI Code Review


Diamond allows you to:

  • Merge PRs faster: Diamond automatically catches bugs and errors before human reviewers, letting your team spend less time on code review, and more time on building.
  • Enforce quality & consistency: Customize Diamond with repo-specific AI prompts and regex rules to enforce best practices across your entire team.
  • Keep your code private & secure: Diamond doesn't store or train on your team's code - your data remains yours.

The Results

The impact of Graphite speaks for itself. Tens of thousands of engineers at leading companies like Asana, Ramp, Tecton, and Vercel rely on Graphite daily to improve their development workflows.

Across these companies and many others, the average engineer using Graphite has seen some impressive results:

  • 1.3x's the number of PRs in flight: Engineers can manage and work on more changes concurrently.
  • Saves ~10 hours a week waiting to merge PRs: Less time spent blocked means more time spent building.
  • Merges 26% more PRs: A more efficient review process leads to a higher throughput of merged code.
  • Ships 20% more code (despite decreasing median per-PR size by 8%): Smaller, more frequent merges contribute to a higher overall shipping velocity.

These statistics highlight the tangible benefits that Graphite brings to engineering teams, translating directly into increased productivity and faster delivery cycles.

A Comprehensive Toolkit

Graphite isn't just about stacked PRs and AI; it's a comprehensive platform packed with features designed to streamline the entire software development lifecycle.

The platform includes:

  • CLI tool: For seamless integration with your existing Git workflow and powerful control over stacked PRs.
  • AI Code Review Companion: Providing intelligent, automated feedback directly on your pull requests.
  • VS Code Extension: Bringing the power of Graphite directly into your code editor.
  • Pull Request Inbox: A centralized hub for managing and prioritizing code reviews.
  • Code Review Tool: Offering a focused and efficient interface for reviewing code changes.
  • Workflow Automation Engine: Allowing teams to customize and automate their code review and merge processes.
  • Merge Queue: Ensuring smooth and automated merging of pull requests once they're approved.
  • Developer Productivity Insights: Providing valuable data and analytics to help teams understand and improve their development process.
Graphite – Developer Insights
Graphite – Developer Insights


All these components are thoughtfully designed to make the software development process as streamlined and effortless as possible.

How to Get Started with Graphite

Ready to experience the benefits of Graphite for yourself? The platform offers a free tier for small teams, making it easy to get started. Simply create your account by signing up with your email or GitHub account.

Give Graphite a try and see how it can help your team unlock new levels of productivity and efficiency in your development workflow!

]]>
Celebrating 20 Years of Git: 20 Interesting Facts From its Creator https://www.git-tower.com/blog/git-turns-20 https://www.git-tower.com/blog/git-turns-20 Thu, 17 Apr 2025 00:00:00 +0000 On April 7, 2005, a seemingly simple tool emerged that would fundamentally reshape the landscape of software development. Git, created by Linus Torvalds, was initially designed to solve a very specific problem: managing Linux kernel development after the departure of BitKeeper.

While many in the tech world might be aware of the remarkable speed at which Git's core functionalities were conceived – famously within a mere 10 days – the full story behind its creation and evolution is rich with surprising details and fascinating insights.

To celebrate this milestone, Linus was recently featured on GitHub's official YouTube channel (you can watch the video below or read the full interview with Taylor Blau). We thought this would be a great opportunity to present this conversation to the Tower community.

In this insightful conversation, Torvalds reflects on:

  • the origins of his groundbreaking project
  • his initial expectations (or lack thereof)
  • the key decisions that shaped Git into the ubiquitous version control system we know today.


Join us as we celebrate two decades of Git by exploring these engaging tidbits straight from the mind of its legendary creator!

Here are 20 interesting (and fun) facts about the early days of Git.

The original transcript has been lightly edited for the purpose of this blog post.

20 Facts About Git

1. Git was born out of necessity to solve a specific problem.

Linus Torvalds didn't embark on creating Git with the goal of global domination in mind. His primary motivation was to solve his own immediate problem: the need for a better version control system for the Linux kernel development. He had a strong negative opinion of existing systems like CVS and even felt his initial, raw version of Git was already an improvement.

"I saw it as a solution to my problems, and I obviously thought it was superior. Even literally 20 years ago to the day, I thought that first version, which was pretty raw — to be honest, even that version was superior to CVS."

2. The initial version of Git was developed in approximately 10 days.

While the groundwork and conceptualization took longer, the intensive coding period to get a working version of Git for kernel use was remarkably short, highlighting Linus's deep understanding of the requirements.

"It was actually fewer than — well, it was about 10 days until I could use it for the kernel, yes. But to be fair, the whole process started like December or November the year before, so 2004."

3. The reverse engineering of BitKeeper ultimately led to Linus creating Git.

The commercial nature of BitKeeper and the restrictions it placed on reverse engineering caused friction within the open-source kernel community. When this led to the loss of free BitKeeper usage, Linus felt compelled to create an open-source alternative.

"What did come up was that Tridge in Australia basically reverse engineered BitKeeper, which wasn’t that hard because BitKeeper internally was basically a good wrapper around SCCS, which goes back to the 60s. SCCS is almost worse than CVS. But that was explicitly against the license rules for BitKeeper. BitKeeper was like, you can use this for open source, but you can’t reverse engineer it. And you can’t try to clone BitKeeper. And that made for huge issues."

4. Linus spent about four months mentally planning the design of Git before writing the initial code.

The ten-day coding sprint was preceded by a significant period of thinking through the problems he wanted to solve and how Git could improve upon existing systems without infringing on BitKeeper's licensing.

"So by the time I started writing Git, I had actually been thinking about the issue for four months and thinking about what worked for me and thinking about “How do I do something that does even better than BitKeeper does but doesn’t do it the way BitKeeper does it?” I did not want to be in the situation where Larry would say, “Hey, you did the one thing you were not supposed to do.” So yes, the writing part was maybe 10 days until I started using Git for the kernel, but there was a lot of mental going over what the ideas should be."

5. For Linus, programming Git in userspace felt easier than dealing with the complexities of kernel development.

Working on a userspace tool allowed Linus to focus on higher-level logic without the low-level memory management and hardware considerations inherent in kernel development.

"And it was kind of interesting because it was — one of my reactions was how much easier it is to do programming in the userspace. There’s so much less you need to care about. You don’t need to worry about memory allocations. You don’t need to worry about a lot of things. And debugging is so much easier when you have all this infrastructure that you’re writing when you’re doing a kernel. So it was actually somewhat — I mean, I wouldn’t say relaxing, but it was fun to do something userspace-y where I had a fairly clear goal of what I wanted. I mean, a clear goal in the sense I knew the direction. I didn’t know the details."

6. A primary design goal for Git was performance, particularly in efficiently applying large series of patches.

Linus wanted Git to handle the numerous patches involved in kernel development quickly, aiming for operations that wouldn't even require a coffee break.

"But for me, one of the goals was that I could apply a patch series in basically half a minute, even when it was like 50, 100 patches. It’s one of those things where if things are just instant, some mistake happens, you see the result immediately and you just go on and you fix it. And some of the other projects I had been looking at took like half a minute per patch, which was not acceptable to me. And that was because the kernel is a very large project and a lot of these SCMs were not designed to be scalable."

7. The use of SHA-1 hashes in Git was primarily for detecting data corruption and ensuring stability, rather than for security purposes.

While SHA-1 provides a level of cryptographic security, Linus's main concern was data integrity, learning from issues encountered with BitKeeper's approach to data protection.

"And people kind of think that using the SHA-1 hashes was a huge mistake. But to me, SHA-1 hashes were never about the security. It was about finding corruption. Because we’d actually had some of that during the BitKeeper things, where BitKeeper used CRCs and MD5s, right, but didn’t use it for everything. So one of the early designs for me was absolutely everything was protected by a really good hash."

8. Git's low-level design is intentionally simple.

Linus drew a parallel to Unix's design philosophy, where a few fundamental ideas underpin a powerful and versatile system.

"Unix has like a core philosophy of everything is a process, everything is a file, you pipe things between things. And then the reality is it’s not actually simple. I mean, there’s the simple concepts that underlie the philosophy, but then all the details are very complicated. I think that’s what made me appreciate Unix in the first place. And I think Git has some of the same kind of, there’s a fundamental core simplicity to the design and then there’s the complexity of implementation."

9. Linus believes that the effort to support SHA-256 in addition to SHA-1 was largely a waste of time and resources, driven by unnecessary worry.

While understanding the concerns, he felt there wasn't a genuine need for the dual-hashing approach and that it led to "pointless churn."

"Well, I mean, SHA-1 I regret in the sense that I think it caused a lot of pointless churn with the whole “trying to support SHA-256 as well as SHA-1.” And I understand why it happened, but I do think it was mostly pointless. I don’t think there was a huge, real need for it, but people were worried, so it was short. So I think there’s a lot of wasted effort there."

10. During the initial development, Linus had a clear vision for the immediate steps but wasn't entirely certain about how all the pieces would ultimately fit together.

While he quickly achieved the ability to apply patches, other core functionalities like merging took more time and he wasn't always sure he would reach his goals.

"I had a clear idea of the initial stages but I wasn’t sure how it would work in the long run. So honestly, after the first week, I had something that was good for applying patches, but not so much for everything else. I had the basics for doing merges, and the data structures were in place for that, but it actually took, I think it took an additional week before I did my first merge. There were a number of things where I had kind of the big picture and result in mind, but I wasn’t sure if I’d get there."

11. The very first versions of Git were rudimentary because there was a more important project to prioritize.

The initial focus was on getting the core functionality working for kernel development, with robustness and more advanced features added over time.

"Yeah, the first steps, I mean the first week or two, I mean, you can go and look at the code — and people have — and it is not complicated code. I think the first version was 10,000 lines or something. You can more or less read it in a single sitting. Yeah, and it’s fairly straightforward and doesn’t do a lot of error checking and stuff like that. It’s really a, “Let’s get this working because I have another project that I consider to be more important that I need to get back to.” It really was."

12. Early Git usage involved direct manipulation of low-level "plumbing commands" and manual editing of files.

Basic operations like committing required arcane sequences of commands that directly interacted with Git's underlying object store.

"I mean, the first week when I was using it for the kernel, I was literally using the raw, what are now called “plumbing commands” by hand. Of course. Because there was no so-called porcelain. There was nothing above that to make it usable. So to make a commit, you’d do these very arcane things. Set your index, commit-tree. Yeah, commit-tree, write, and that just returns an SHA that you write by hand into the head file and that was it."

13. The hash-object command, fundamental for Git's content-addressable storage, was one of the earliest binary utilities Linus created.

This allowed him to verify the core hashing mechanism by manually hashing data and checking the output.

"I think that was one of the first binaries that I had where I could just check that I could hash everything by hand and it would return the hash to standard out, then you could do whatever you wanted to it."

14. The initial user interface "porcelain" for Git consisted of shell scripts written by Linus to wrap the difficult-to-use plumbing commands.

Making Git accessible required building higher-level tools on top of the core commands. Linus's initial attempts were in the form of simple scripts, which weren't particularly user-friendly.

"But it was like the early porcelain was me scripting shell scripts around these very hard-to-use things. And honestly, it wasn’t easy to use even with my shell scripts."

15. The first target audience for Git was the hardcore kernel developers who were already familiar with some of the concepts from using BitKeeper.

Their prior experience with a more advanced VCS made them more receptive to Git's underlying ideas.

"But to be fair, the first initial target audience for this were pretty hardcore kernel people who had been using BitKeeper. They at least knew a lot of the concepts I was aiming for. People picked it up."

16. Linus handed over the maintainership of Git to Junio Hamano relatively early in the project.

After only three or four months of his own stewardship, Linus recognized the need to focus on the kernel and trusted Junio's capabilities to lead Git's further development.

"I mean, to be honest, I maintained Git for like three or four months. I think I handed it off in August [of 2005] or something like that. And when I handed it off, I truly just handed it off. I was like, “I’m still around.” I was still reading the Git mailing list, which I don’t do anymore. Junio wanted to make sure that if he asked me anything, I’d be okay. But at the same time, I was like, this is not what I want to do."

17. Linus's criteria for choosing Junio as the maintainer was largely based on his "taste" in code.

He valued Junio's judgment and his understanding of the project's direction.

"But to be honest I’ll take credit for having worked with people on the internet for long enough that I was like — during the four months I was maintaining Git, I was pretty good at picking up who has got the good taste to be a good maintainer. That’s what it’s about — taste — for you. For me, it’s hard to describe. You can see it in patches, you can see it in how they react to other people’s code, “how they think” kind of things."

18. Git's distributed nature, where every repository is a full copy with complete history, was a key design principle.

This architecture made local work and later sharing incredibly easy. It also differentiated it from most previous centralized version control systems and contributed to its widespread adoption.

"So the distributed nature really ends up making so many things so easy and that was one big part that set Git apart from pretty much all SCMs before, was… I mean there had been distributed SCMs, but there had, as far as I know, never been something where it was like the number one design goal — I mean, along with the other number one design goals — where it means that you can work with Git purely locally and then later if you want to make it available in any other place it’s so easy. And that’s very different from, say, CVS where you have to set up this kind of repository and if you ever want to move it anywhere else it’s just very very painful and you can’t share it with somebody else without losing track of it."

19. Linus believes that Git's fundamental design, emphasizing easy copying and the equality of all repositories, made services like GitHub "trivial" at their core.

The underlying architecture of Git facilitated the creation of centralized hosting platforms.

"And the fact that Git didn’t do that, and very much by design didn’t do that, I mean that’s what made services like GitHub trivial. I mean I’m trivializing GitHub because I realized there’s a lot of work in making all the infrastructure around Git, but at the same time the basic Git hosting site is basically nothing because the whole design of Git is designed around making it easy to copy, and every repository is the same and equal."

20. Linus was amused by the initial wave of complaints about Git's user interface, particularly the naming of commands, as he sometimes deliberately chose different names than CVS simply because he disliked it.

The transition from older systems led to confusion and criticism, but Linus had his own reasons for some of the seemingly arbitrary choices.

"Oh, the complaints kept coming. Tell me about it. Oh, I mean, it’s more like I can’t point to details. You’d have to Google it. But the number of people who sent me, “Why does it do this?” And the flame wars over my choice of names. For example, I didn’t have git status, which actually is one of the commands I use fairly regularly now... So I just remember the first few years, the complaints about why the names of the subcommands are different for no good reason. And the main reason was I just didn’t like CVS very much, so I did things differently on purpose sometimes."

Final Words

So there you have it: 20 interesting facts about the early days of Git!

Here at Tower, as passionate fans and dedicated users of Git ourselves, we join the global community in celebrating this remarkable 20-year milestone. We recognize and appreciate the profound influence Git has had on our daily work and the collaborative spirit of software development as a whole.

Here's to many more years of Git! 🥂

We hope you found this post helpful. For more Git tips and tricks, don't forget to sign up for our newsletter below and follow Tower on Twitter / X and LinkedIn! ✌️

]]>
How to Exclude Commits from Git Blame https://www.git-tower.com/blog/how-to-exclude-commits-from-git-blame https://www.git-tower.com/blog/how-to-exclude-commits-from-git-blame Wed, 16 Apr 2025 00:00:00 +0000 Ah, git blame! The detective of Git-land, diligently pointing its finger at the author of each line of code. But sometimes, the blame game can get a little… noisy.

What if you're trying to understand the evolution of a critical piece of logic, but all you see are commits related to code formatting or a massive refactoring that touched almost every file? These commits, while important in their own right, can sometimes obscure the more granular history you're trying to uncover.

Thankfully, there are ways to tell git blame to politely ignore certain commits, allowing you to focus on the changes that truly matter. This is what this article is all about.

Today, we will explore the situations in which it makes sense to exclude commits and examine our options.

But first, here's a brief overview of the purpose of git blame.

About the "Git Blame" Command

At its core, git blame is a Git command that displays the author and revision information for each line of a file.

The primary purpose of this command is to understand the history of a specific piece of code. It helps you answer questions like:

  • Who wrote this line of code?
  • When was this line last changed?
  • Why was this change made (by examining the commit message)?

It works by traversing the commit history of a file; starting from the current version of the file, it looks back through the commits that have modified it, line by line. For each line, it identifies the commit that introduced or last changed that particular line.

Git cleverly tracks line movements across commits. So, if a line of code is moved to a different location within the same file or even to another file (in some cases), git blame can often still trace its original author and commit.

This makes it a powerful tool for understanding the evolution of your codebase — way more reliable than your colleague John!

John versus Git Blame!
John versus Git Blame!


Jokes aside, for every line in the specified file, git blame shows:

  • The commit hash of the last commit that modified that line.
  • The author of that commit.
  • The date and time of that commit.
  • The actual line of code.

This information is essential for debugging, understanding legacy code, and collaborating effectively within a team.

Why Exclude Commits From Git Blame?

While git blame is incredibly useful, there are scenarios where certain types of commits can clutter the output and make it harder to find the information you're really looking for.

Imagine the following situations:

  • Massive Code Formatting: Your team decides to adopt a stricter code style and runs an automated formatter across the entire codebase. This results in a commit that touches almost every line of every file, but doesn't change any functional logic.
    Running git blame after this commit might show the formatter as the author of large sections of the code, obscuring the original authors and the actual evolution of the logic.
  • Large-Scale Refactoring: A significant refactoring effort might involve moving code around, renaming variables, or restructuring directories without fundamentally changing the behavior of the code. These commits can also dominate the git blame history, making it difficult to see the more fine-grained changes.
  • Automated Script Changes: Commits generated by automated scripts, such as dependency updates or generated code, might not provide much useful context when you're trying to understand the human-written parts of the code.
  • Cherry-Picks and Merges: Sometimes, cherry-picking or merging commits can result in changes that don't accurately reflect the original authorship in the target branch's history. Excluding the merge commit itself might provide a cleaner view of the individual contributions.

This is where the ability to exclude commits comes in handy. So let's have a look at how it works in practice.

How to Exclude Commits from Git Blame

Git provides a couple of powerful ways to exclude specific commits from the git blame output:

  • Option 1: Creating a .git-blame-ignore-revs File
  • Option 2: Command-Line Options for git blame

Let's explore both methods.

Option 1: Creating a .git-blame-ignore-revs File

The .git-blame-ignore-revs file is a configuration file that allows you to specify a list of commit hashes (or SHAs — Secure Hash Algorithm) that git blame should ignore.

💡 Please note that .git-blame-ignore-revs is merely a convention; Git does not automatically use this file in the same manner as it does with the .gitignore file.

However, we recommend using this file name, as popular code hosting platforms like GitHub and GitLab look for and support this file.

1. Creating and Using the File

To use this feature, you first need to create a file named .git-blame-ignore-revs at the root of your Git repository. This file should contain a list of commit hashes/SHAs, with one hash per line.

For example, your .git-blame-ignore-revs file might look like this:

# Removed semi-colons from the entire codebase
a1b2c3d4e5f678901234567890abcdef01234567
# Converted all JavaScript to TypeScript
fedcba9876543210fedcba9876543210fedcba98

Each line in this file represents a commit that you want git blame to skip over when tracing the history of a file. Comments are optional but recommended.

2. Syntax for Listing Commits to Ignore

The syntax for the .git-blame-ignore-revs file is straightforward: simply list one full commit hash per line. You can obtain these hashes using commands like git log or by inspecting your Git history in Tower.

Finding the Commit Hash in Tower
Finding the Commit Hash in Tower


It is important to use the full SHA-1 hash to ensure Git correctly identifies the commits to ignore.

3. Configuring Git to Use the File

Once you've created and populated the .git-blame-ignore-revs file, you need to tell Git to actually use it. You can do this by setting the blame.ignoreRevsFile configuration option.

To enable this for your current repository, run the following command in your terminal:

git config blame.ignoreRevsFile .git-blame-ignore-revs

To enable it globally for all your Git repositories, use the --global flag:

git config --global blame.ignoreRevsFile .git-blame-ignore-revs

With this configuration in place, whenever you run git blame on a file in your repository (or any repository if you used the --global option), Git will automatically skip over the commits listed in your .git-blame-ignore-revs file.

If a line's last modification was in an ignored commit, git blame will continue to trace the history back to the commit before the ignored one.

Option 2: Command-Line Options for git blame

For more ad-hoc or one-off exclusions, git blame also provides command-line options to ignore specific commits or an ignore file.

1. The --ignore-rev Option

The --ignore-rev option allows you to specify one or more commit hashes/SHAs directly in your git blame command.

To ignore a single commit, you would use:

git blame --ignore-rev <commit-sha> <file>

To ignore multiple commits, you can use the option multiple times:

git blame --ignore-rev <commit-sha-1> --ignore-rev <commit-sha-2> <file>

This option is useful when you quickly want to exclude a specific commit without modifying the .git-blame-ignore-revs file.

2. The --ignore-revs-file Option

If you have a file containing the list of commits to ignore (which doesn't necessarily have to be named .git-blame-ignore-revs or located at the repository root), you can explicitly tell git blame to use it with the --ignore-revs-file option:

git blame --ignore-revs-file <path/to/ignore-file> <file>

This can be helpful if you want to maintain different ignore lists for different purposes or if you prefer to keep the ignore list in a non-standard location.

Best Practices for Excluding Commits

While the ability to exclude commits from git blame is powerful, it's important to use it judiciously and follow some best practices.

Here are 4 tips you should keep in mind.

1. Maintaining the Ignore List

If you choose to use the .git-blame-ignore-revs file, it's important to maintain it over time. As your project evolves, you might encounter new formatting or refactoring commits that you want to add to the ignore list.

Consider keeping the ignore list relatively concise and focused on truly disruptive commits. A very long ignore list might indicate a broader issue with your commit history or development practices.

2. Communicating Excluded Commits to the Team

If you are using the repository-specific .git-blame-ignore-revs file (i.e., you configured blame.ignoreRevsFile without the --global flag), it's a good idea to communicate to your team that this file exists and what types of commits are being ignored. This ensures that everyone on the team is aware of the potential differences in their git blame output.

Since .git-blame-ignore-revs is typically committed to the repository, it automatically shares the ignore list with everyone who clones the project. However, it's still helpful to mention its existence in your project's documentation or during team meetings.

3. Balancing Exclusion with Accountability

While excluding certain commits can improve the clarity of git blame output, it's important to maintain accountability. Don't use commit exclusion as a way to hide authorship of problematic code. The primary goal is to improve the signal-to-noise ratio, not to rewrite history or evade responsibility.

Remember that the excluded commits are still part of the Git history and can be examined using other Git commands like git log. git blame with exclusions simply provides a filtered view.

4. Integrating Exclusion into Your Workflow

Consider integrating the creation or updating of the .git-blame-ignore-revs file as part of your team's workflow when performing large-scale formatting or refactoring. For example, the script that performs the formatting could also generate or append to the ignore list.

Using a repository-specific .git-blame-ignore-revs file and enabling it via git config within the repository ensures that the ignore rules are automatically applied for everyone working on that project. This provides a consistent and cleaner git blame experience for the entire team.

Final Words

We've journeyed through the ins and outs of excluding commits from git blame, from understanding its purpose to mastering the techniques for filtering out noise.

Whether you choose to use the .git-blame-ignore-revs file for persistent exclusions or the command-line options for more targeted filtering, you now have the tools to make your code history investigations more focused and efficient. So go ahead and use these techniques wisely!

We hope you found this post helpful. For more Git tips and tricks, don't forget to sign up for our newsletter below and follow Tower on Twitter / X and LinkedIn! ✌️

]]>
Tower 9.0 for Windows — Git Worktree Support https://www.git-tower.com/blog/tower-windows-9 https://www.git-tower.com/blog/tower-windows-9 Mon, 31 Mar 2025 00:00:00 +0000 For those of you eagerly awaiting Git Worktree support in Tower, your patience has paid off! We're thrilled to announce that Tower 9.0 for Windows brings this powerful feature directly to your favorite Git client.

After bringing Git Worktree support to Tower for Mac earlier this year, it's now Windows' turn! With this release, you can easily create, check out, and manage Worktrees right from within Tower!

Let's first explore what makes git-worktree so useful and then see how easy it is to perform all Worktree operations in Tower.

The Power of "Git Worktree"

In short, git-worktree allows you to simultaneously work on different branches without the usual conflicts and disruptions. This is a game-changer when you need to switch gears for urgent tasks, like a hotfix, without interrupting your current work.

Traditionally, you might have resorted to:

  • Stashing your changes, which can be cumbersome and prone to forgotten details.
  • Creating incomplete commits, which require later edits and can clutter your history.

With worktrees, you can seamlessly transition between branches or pull requests, maintaining a clean and organized workflow 😎

Another significant advantage is handling long-running processes. You can execute time-consuming operations like builds or tests in one worktree while continuing development in another, ensuring uninterrupted productivity.

Worktrees differ from branches in their directory structure. Each worktree has its own distinct working directory — which is why it is recommended to create worktrees outside your main project folder, to avoid redundancy.

Furthermore, worktrees are resource-efficient. They share the underlying Git repository data (objects and refs), minimizing disk space usage compared to multiple clones and offering faster performance.

Worktrees in Tower for Windows

Tower provides an intuitive interface for managing and switching between worktrees.

With this new update, you will notice a dedicated "Worktrees" section conveniently located in the sidebar, following "Submodules".

Tower 9.0 – Worktrees in the sidebar
Tower 9.0 – Worktrees in the sidebar

Creating a New Worktree

There are several ways to create a new worktree in Tower. One method is to right-click on any branch and select "Check out [BRANCH] in New Worktree..." from the context menu.

Tower 9.0 – Creating a New Worktree from the Context Menu
Tower 9.0 – Creating a New Worktree from the Context Menu


Alternatively, you can use the "+" button at the bottom of the sidebar or navigate to "Repository" > "Add New Worktree…" in the main menu.

Tower 9.0 – Creating a New Worktree by clicking the
Tower 9.0 – Creating a New Worktree by clicking the "+" button


In the dialog box, specify the desired location for the worktree and the branch to use as a starting point.

Upon clicking "Create Worktree", a new worktree will be generated and automatically checked out, ready for use!

Tower 9.0 – Creating a New Worktree dialog
Tower 9.0 – Creating a New Worktree dialog


Fans of drag-and-drop actions will appreciate that you can easily drag a branch to the "worktree" section to instantly create a worktree based on that branch. By the way, this also works with commits, not just branches 😉

Creating a New Worktree with Drag and Drop

Managing Worktrees in Tower

Tower visually distinguishes worktrees with a unique icon within the "Branches" section, making them easily identifiable.

Tower 9.0 – Worktrees in the
Tower 9.0 – Worktrees in the "Branches" section


Right-clicking on a worktree provides options to remove it, relocate it, or open it in the terminal or Explorer, offering comprehensive control.

Tower 9.0 – Worktree options
Tower 9.0 – Worktree options


A New Compact Top Bar Layout

With this release, we've also introduced a new compact top bar layout for a cleaner appearance.

Tower 9.0 – Compact Top Bar Layout
Tower 9.0 – Compact Top Bar Layout


To try it out, enable "Use compact top bar layout" in "Preferences > General." Changes will be applied after restarting Tower.

Tower 9.0 – Enabling the Compact Top Bar Layout
Tower 9.0 – Enabling the Compact Top Bar Layout


Other Improvements

As always, we've also taken a moment to address some other small improvements and bug fixes, such as:

  • SSH Keys: Fixed retrieval from 1Password.
  • Rebase: Fixed commit message editing during rebase operations.
  • Services: Fixed issues with adding custom accounts and GitLab authentication issues.
  • Ignore & Exclude Files: Fixed an issue where these files did not open correctly. They now function as expected.
  • Cherry-Picking: Fixed the issue where commits were applied in the wrong order, ensuring they now follow the expected sequence.

For the complete changelog, please have a look at the Release Notes.

We hope you enjoy our latest Windows release. Happy committing! 😊

New to Tower? Download our 30-day free trial and discover a more efficient way to work with Git!




PS: Did you know? Tower Pro is now free for students as well as teachers and educational institutions!

]]>
The Honest Git Glossary https://www.git-tower.com/blog/honest-git-glossary https://www.git-tower.com/blog/honest-git-glossary Tue, 11 Feb 2025 00:00:00 +0000 The Honest Git Glossary is a fun (and honest!) way to learn the most popular Git commands.

Have a laugh and share it with your developer friends!


The Honest Git Glossary
The Honest Git Glossary


We hope you find this fun cheat sheet helpful…

…but if you're tired of Googling commands, we invite you to try Tower, our Git client, available for both Mac and Windows!

Tower app icon
]]>
Tower 12.5 for Mac — Hello Worktrees! 👋 https://www.git-tower.com/blog/tower-mac-125 https://www.git-tower.com/blog/tower-mac-125 Wed, 05 Feb 2025 00:00:00 +0000 Tower 12.5 for Mac is here, bringing one of our users' most requested features: Worktree support! Now you can create, check out, and manage Worktrees directly from within your favorite Git client! 🫡

If you are a fan of worktrees and have been hoping for Tower to support them, we have great news for you: the wait is over!

Let's take a look at this native Git feature and explore what you can do in Tower.

What is "Git Worktree" all about?

The git-worktree feature was introduced in version 2.5.0 of Git. The main advantage is that it allows you to have multiple working trees attached to the same repository, enabling you to check out more than one branch simultaneously from a single repository.

This is especially useful when someone asks you to work on a hotfix, for example, requiring you to leave your current work unfinished.

In such cases, with regular branches, you would either need to:

  • stash your changes to check out a different branch
  • create an unfinished commit, which you might need to edit later... if you remember to do so!

With worktrees, you can check out as many branches or pull requests as you'd like without worrying about having a clean working copy 😎

Another great use case is for long-running operations. You can perform time-consuming tasks, such as large builds or extensive tests, in one worktree while continuing to work in another. Worktrees are great for staying in the flow!

There are other differences to keep in mind when compared to branches. Unlike branches, which share the same working directory, each worktree has its own distinct working directory. It is best to create your worktrees outside of your project folder, as you wouldn't want a duplicate copy of your files inside your current worktree.

Your hard drive will also appreciate worktrees, as they are more lightweight. All worktrees share the same Git repository data (objects and refs), which saves disk space compared to having multiple clones and is generally faster than creating a new clone of the repository.

Now that you can see the benefits of this feature, let's see how you can work with Worktrees in Tower.

Working with Worktrees in Tower

Tower makes it easy to manage your worktrees and quickly check them out. You can find a new "Worktrees" section available in the sidebar, after "Submodules".

Tower 12.5 – Worktrees in the sidebar
Tower 12.5 – Worktrees in the sidebar

Creating a New Worktree

Creating a new worktree in Tower couldn't be easier: simply right-click any branch and select "Check out [BRANCH] in New Worktree..." from the context menu.

Tower 12.5 – Creating a New Worktree from the Context Menu
Tower 12.5 – Creating a New Worktree from the Context Menu


Alternatively, you can click the "+" button located at the bottom of the sidebar or select "Repository" > "Add new Worktree…" from the main menu.

Tower 12.5 – Creating a New Worktree by clicking the
Tower 12.5 – Creating a New Worktree by clicking the "+" button


In the dialog, you will be prompted to select the location where you would like the worktree to be saved, as well as the branch you would like to use as a starting point.

After clicking "Create Worktree", a new worktree will be created and automatically checked out!

Tower 12.5 – Creating a New Worktree dialog
Tower 12.5 – Creating a New Worktree dialog


Managing Worktrees in Tower

Worktrees have a distinct icon, making it easy to identify when a branch is checked out in a worktree.

Tower 12.5 – Worktrees in the
Tower 12.5 – Worktrees in the "Branches" section


By right-clicking on any worktree, you can remove it, move it to a new location, or explore it in the terminal or Finder by selecting the appropriate option from the context menu.

Tower 12.5 – Worktree options
Tower 12.5 – Worktree options


We hope you enjoy this release! Happy committing! 😊

Not a Tower user yet? Download our 30-day free trial and experience a better way to work with Git!




PS: Did you know? Tower Pro is now free for students as well as teachers and educational institutions!

]]>
Markdown's Big Brother: Say Hello to AsciiDoc https://www.git-tower.com/blog/asciidoc-quick-guide https://www.git-tower.com/blog/asciidoc-quick-guide Tue, 21 Jan 2025 00:00:00 +0000 We’ve all been there: a single README.md file was enough in the early days of your project. But as new features and contributors rolled in, maintaining that lightweight Markdown file started feeling like juggling knives.

Suddenly you needed tables, cross-references, conditional text, and more. Your once-lean documentation stack was becoming a tangle of extensions, custom scripts, and half-baked solutions. Enter AsciiDoc!

If you’ve been relying on Markdown and occasionally fighting its quirks, AsciiDoc might be the structured, fully-featured alternative you didn’t know you needed. In this guide, we’ll walk through AsciiDoc’s essentials and share tips on how to make your documentation easier to maintain, especially if you’re using version control tools like Git (and even better if you’re using Tower).

Markdown vs. AsciiDoc – An Overview

Markdown’s Strengths (and Limitations)

No one’s knocking Markdown. It’s famous for:

  • Simplicity: You can learn the basics in minutes (# Heading, - Lists, **Bold**).
  • Widespread Support: From GitHub to countless blogging platforms, Markdown is everywhere.
  • Readable Syntax: Markdown files look decent even in raw form.

However, Markdown can become cumbersome when your docs grow large or require advanced features. To handle tables, footnotes, or custom formatting, you often rely on third-party extensions. That’s where compatibility headaches can pop up.

AsciiDoc’s Superpowers

By contrast, AsciiDoc was built to tackle complex documentation without relying on scattered extensions. Out of the box, it handles:

  • Tables, footnotes, and cross-references with minimal fuss.
  • Document composition: Include or reference multiple AsciiDoc files to keep large projects organized.
  • Attributes and conditional content for flexible, multi-version outputs.

AsciiDoc has a unified ecosystem rather than a million “flavors” or "dialects". If you’ve ever battled Markdown dialects, you’ll appreciate the consistency.

To sum it up: AsciiDoc is Markdown on Steroids.

Writing in AsciiDoc - An Example

Let’s say you’re documenting the user guide for an application. Let's see how we can set it up in AsciiDoc:

Setting the Stage: Document Metadata

AsciiDoc doesn’t force you to create a separate config file for metadata. You can embed it directly in the document header:

= User Guide for adoc Studio
Author: Marvin Blome
Date: 2025-01-21

That’s it. You get a title, author, and date right in your source file. No extra YAML required.

Organizing with Headings

Next up, we want to outline our document's structure. For this, we use headings. In AsciiDoc, they are written with = signs. The number of equals signs corresponds to the heading level:

= User Guide for adoc Studio
== Basic Topics
=== Features
=== Installation
== Advanced Topics
=== ...

It’s readable and easy to spot your document’s structure at a glance, even if you’re looking at the raw text.

Text Formatting - Similar to Markdown

If you’ve used Markdown, you’ll feel right at home with AsciiDoc’s basic text styling:

*Bold Text*
_Italicized Text_
`Monospaced Text`

Rendered, these become bold, italic, and monospaced respectively.

Text Formatting in AsciiDoc
There are plenty of formatting options in AsciiDoc

Making Content Scannable via Lists

Let’s be honest, most readers skim for the key points. That’s where lists come in handy, and setting them up in AsciiDoc couldn’t be easier:

// Unordered List
* Item 1
* Item 2

// Ordered List
. Step 1
. Step 2
. Step 3

Ordered lists automatically re-number if you move items around – no awkward re-typing of numbering.

Tables Without Tears

When Markdown tables get complicated, you often fall back on hacky solutions or HTML. AsciiDoc tables, on the other hand, use a simple grid syntax:

|===
| Task | Status | Due Date
| Write draft | In Progress | Jan 20, 2025
| Review draft | Pending | Jan 22, 2025
|===

This is a breeze to maintain in version control because each table row is on its own line. That means clear diffs in Git, without the confusion of multi-line Markdown tables.

Quick Tip: Use the Apple Text Replacement to insert table templates. Create a shortcut like table() and watch it expand into a skeleton table.

Attributes: Reusable Variables

Ever wish you could define a variable once and reuse it everywhere? That’s what attributes are for in AsciiDoc.

Attributes in AsciiDoc
Attributes in AsciiDoc


Change :app-name: and other attributes in the definition, and they update across your document. Perfect for version numbers, website URLs and other recurring text.

Splitting Your Docs: Include Directive

Large teams (and large documentation projects) benefit from modular files. Instead of one giant .adoc file, you can keep each section separate and include them dynamically:

include::introduction.adoc[]
include::features.adoc[]

Imagine a scenario where your advanced tips only apply to the enterprise version of your software. Keep them in a separate file and include them only where you need them.

Conditional Content

Take modularity a step further by toggling content based on attributes. This is especially handy if you maintain both a beginner guide and an advanced guide:

ifdef::beginner[]
== Welcome, New Users!
endif::[]

ifdef::advanced[]
== Advanced Tips and Tricks
endif::[]

Activate those attributes in the text or directly in the export. With that, you can create multiple outputs from a single master document.

Exporting AsciiDoc Files

Once you’ve harnessed AsciiDoc’s advanced features, the next question is: How do you export all this work? Typically, you’d hop into a terminal and run commands like asciidoctor -b html5 myfile.adoc. Here you'd need to create and maintain long scripts for every format and export.

This is where adoc Studio comes into play.

adoc Studio’s Approach


adoc Studio is an AsciiDoc editor that bundles everything you need to write, organize, and export your docs in one place. Rather than juggling scripts or dealing with multiple tools for PDF, HTML, or other formats, you can define your:

  • Attributes (like beginner or advanced)
  • Formats (HTML, PDF, etc.)
  • Stylesheets (for consistent branding across documents)

…and store them as “products” in the app. This keeps your writing flow uninterrupted and your design consistent.

Attributes Product Example
Attributes Product Example


If you need a quick refresher on syntax while writing, the built-in adoc Coach pops up with suggestions. Just hit ESC and explore what’s possible in your current context.


While AsciiDoc itself is platform-agnostic, editors like adoc Studio can make the experience more efficient:

  • Unified Styles: While AsciiDoc requires individual stylesheets for all formats, adoc Studio only requires one CSS for both HTML & PDF.
  • No Terminal Required: If the command line isn’t your friend, the app provides a user-friendly GUI for exports.
  • Mobile-Friendly: adoc Studio is available for Mac, iPad, and iPhone, making quick edits on the go surprisingly easy.
adoc Studio Devices
adoc Studio Devices


If you’re curious, there’s a 14-day free trial. Afterward, you can subscribe monthly or annually.

Docs-as-Code with Git

For many developer teams, documentation is an integral part of the software itself. That’s where Docs-as-Code comes in. By storing your AsciiDoc files in a Git repository, you can:

  1. Collaborate effortlessly – Each pull request shows exactly what changed in your docs, just like you’re used to with code.
  2. Branch and merge safely – Work on future documentation in a separate branch without disturbing your main docs.
  3. Track history – Roll back if something goes wrong or reference how docs have evolved over time.

AsciiDoc plays nicely with Git because it’s plain text. Each line is easily diffed, so you can see changes without wading through messy binary differences. And if you’re using Tower, you get a slick interface to manage your repositories, branches, and merges.

Parting Thoughts

AsciiDoc might look like just another markup language, but under its lightweight syntax lies a powerful engine for creating and maintaining professional documents. Whether you’re producing user guides, release notes, or full-blown technical manuals, AsciiDoc gives you the structure, flexibility, and control that can be elusive in simpler formats.

If you want to learn more about the markup language, check out the Complete Guide to AsciiDoc on adoc Studio's blog.

Happy documenting!

]]>
Tower 8.0 for Windows — Stacked Branches https://www.git-tower.com/blog/tower-windows-8 https://www.git-tower.com/blog/tower-windows-8 Tue, 12 Nov 2024 00:00:00 +0000 The latest version of Tower for Windows introduces a new "Restack Branch" feature, a new "Sync" action, and several visual enhancements to the user interface.

Are you a fan of Stacked Branches? Do you like keeping your local repository in sync with the remote? If so, we believe you'll enjoy this release! 😎

Keep reading to find out all the details about our newest update!

For a demonstration of the new features in action, you can also watch the video below 👇

1. Restack Branches

Tower 8.0 marks the beginning of our ambitious "Tower Workflows" project by introducing "Branch Dependency" functionalities and the new "Restack" feature.

By incorporating Branch Dependencies, Tower can now easily track all the parent branches of a branch and provide the ability to "restack" the branch, along with all its parent branches, back to the "trunk" branch.

Restacking is especially useful for workflows that involve stacked branches, such as the "Stacked Pull Requests" workflow.

Manually updating branches can be a cumbersome task, as each child branch needs to be rebased onto its parent branch. With Tower 8.0, restacking is only a couple of clicks away!

This feature was first introduced in Tower 12 for Mac and has received high praise from our users. Now, Windows users can experience what all the excitement is about!

To get started with the "Stacked Branches" workflow, simply click on the corresponding option in the "Workflow" icon found in the toolbar.

Tower 8.0 for Windows — Enabling the Workflow
Tower 8.0 for Windows — Enabling the Workflow


Tower will first ask you to identify the "Trunk" branch. This is your main development branch for the repository (usually main), where all stacked branches will eventually be merged back. You also have the option to group all child branches under the parent branch for better visualization in the sidebar.

Tower 8.0 for Windows — Configuring Stacked Branches
Tower 8.0 for Windows — Configuring Stacked Branches


This last setting can also be adjusted in Tower's Preferences by locating "Stack branches under parent branch" in the "General" tab.

Tower 8.0 for Windows — Stack Branches Under Parent Branch
Tower 8.0 for Windows — Stack Branches Under Parent Branch


Restacking

When this workflow is enabled, each time the parent branch is updated, a new "restack" icon will appear next to every child branch in the sidebar. Simply right-click on the branch to access the context menu and select the appropriate action!

Moreover, Tower will display a yellow banner in the branch's history view to notify you that it needs to be restacked.

Tower 8.0 for Windows — Restack Branch
Tower 8.0 for Windows — Restack Branch

Choosing a Different Parent Branch

In the context menu shown above, you also have the option to select a different parent branch if you wish, or to unset the branch, which will remove it from its current parent branch.

Tower 8.0 for Windows — Restack Branch
Tower 8.0 for Windows — Restack Branch

2. The New "Sync" Button

Folks who need to synchronize their repository multiple times a day will appreciate the new "Sync" button available with this release!

So, what does this button do? As the name suggest, it executes a "pull" operation and, if that is successful, it follows up with a "push."

This feature is useful for updating a local branch with the most recent changes from a remote repository and then promptly pushing any local commits back to that remote repository.

You can find the new "Sync" button in the toolbar or by pressing CTRL + Y.

Tower 8.0 for Windows — "Sync" button

3. Visual Enhancements

As a native app for both Windows and Mac, Tower adheres to the recommended design languages of each operating system. Although this is more challenging in the Windows environment, we follow all the best practices to ensure that Tower for Windows stands out!

When launching Tower 8.0 for the first time, some visual improvements will be immediately apparent. For instance, you will notice that the in-app accent color is now synchronized with Windows, and the "Mica material" is used as a semi-transparent, softly blurred background.

Tower Windows 8.0 – Visual Enhancements
Tower 8.0 for Windows – Visual Enhancements


We have also shifted the top bar's main menu to the right and implemented window docking support. Oh, and the repository and branch names are now displayed in the taskbar!

4. Other Improvements

In the background, several minor enhancements have been implemented.

Here are some of the areas that have experienced improvements:

  • Services: Creating new repositories on GitLab is now functioning as expected. The incorrect display of GitLab repositories in some groups has also been resolved.
  • Keyboard Shortcuts: Several new keyboard shortcuts have been added to speed up workflows.
  • Repository Settings: The issue with opening the .gitattributes file in an external editor when configuring Git LFS has been fixed.
  • Sidebar: A problem that could cause the application to crash when opening the submodule context menu has been resolved.
  • Directory Detection: The detection of unsafe directories accessed via mapped network drives and their addition to “safe.directories” in gitconfig now works as expected.
  • Installer: The extraction of Portable Git was failing under certain locale settings, but this issue has now been resolved.

Since this release includes quite a lot of improvements under the hood, we encourage you to head over to the Release Notes page for the full rundown.

We hope you enjoy this release. If you already have a Tower account, update today!

Happy committing! 😊

Not a Tower user yet? Download our 30-day free trial and experience a better way to work with Git!




PS: Did you know? Tower Pro is now free for students as well as teachers and educational institutions!

]]>
Understanding the Trunk-Based Development Workflow https://www.git-tower.com/blog/trunk-based-development https://www.git-tower.com/blog/trunk-based-development Mon, 11 Nov 2024 00:00:00 +0000 Are you tired of dealing with long-lived feature branches and complex merge conflicts? Trunk-based Development might be exactly what you need. This workflow has gained significant traction among high-performing engineering teams, particularly those embracing DevOps practices and continuous integration.

In this post, we'll explore what Trunk-based Development is, what makes it unique, its advantages, and, more importantly, who it is intended for.

If you've been working with Git for a while, you're probably familiar with git-flow or perhaps even the "GitHub Flow." These workflows typically involve creating feature branches that can live for days or even weeks before being merged back into the main branch.

While these approaches certainly have their merits, they can sometimes lead to integration challenges and delayed feedback cycles. This is where Trunk-based Development comes in!

What is Trunk-based Development?

Trunk-based Development (TBD) is a source-control branching model where developers collaborate on code in a single branch called "trunk" (traditionally the main or master branch in Git).

The key principle here is simple: keep your changes small and merge them frequently into the main branch.

In its purest form, developers commit directly to the trunk. However, most teams opt for a slightly modified approach where they:

  1. Create short-lived feature branches (usually lasting no more than a day or two)
  2. Merge these branches back into trunk as quickly as possible
  3. Delete the feature branch once it's merged
The Trunk-based Development workflow
The Trunk-based Development workflow


The emphasis here is on "short-lived" — these branches should be merged within hours or, at most, a couple of days. Any longer than that, and you're not really doing Trunk-based Development anymore!

Why Should You Consider Trunk-based Development?

We've already hinted at some of the benefits of this approach in the introduction, but now let's take a closer look at all the advantages of this workflow:

  1. Reduced "Merge Hell": Since changes are integrated frequently and in small chunks, merge conflicts become less frequent and easier to resolve.

  2. Faster Feedback Cycles: Your code gets reviewed and tested more quickly, allowing you to catch and fix issues early in the development process.

  3. Better Collaboration: Everyone works off the same, up-to-date codebase, making it easier to share code and avoid duplicate work.

  4. Simplified CI/CD: With all changes going into a single branch, your CI/CD pipeline becomes more straightforward and efficient.

Despite these advantages, it does not necessarily mean that TBD is the best Git workflow for you and your team. We will explore some of the drawbacks in the next section.

But first, let's address a question that might have come to your mind in the meantime...

Not a Tower user yet?

Download our 30-day free trial and experience a better way to work with Git!

Tower app icon

What About Unfinished Features?

Since this approach focuses on merging code back into the "trunk" as frequently as possible, you might be wondering:

What happens if I'm working on a feature that's not ready to be released yet? 🤔

This is where "feature flags" (also known as "feature toggles") come into play! Instead of using long-lived feature branches to hide incomplete work, you can use feature flags to control which functionality is available to users.

Here's a simple example in PHP:

if (FeatureFlags::isEnabled('new-upvotes-feature')) {
    // New upvoting functionality
    return $this->newUpvotingSystem();
} else {
    // Old functionality or fallback
    return $this->currentUpvotingSystem();
}

This way, you can merge your code into the trunk branch while keeping it hidden from users until it’s ready for release. When the feature is complete and thoroughly tested, you can simply flip the switch!

Is Trunk-based Development Right for Your Team?

While TBD offers many advantages, it's not necessarily the best fit for every team. For example, if you’re working on an open-source project, this approach will not be effective, as you need strict control over changes and cannot fully trust contributors.

The decision should be based on a careful evaluation of your team's skills, processes, and objectives. Here are some questions you should ask yourself:

1. How Experienced Is Your Team?

Your team will be pushing code into the trunk branch very frequently. If you constantly need to supervise and review each merge, a workflow based on feature branches could prove preferable. Frequent integration and quick conflict resolution can be overwhelming for teams with a high proportion of junior developers.

2. Where Does Your Team Stand in CI and Test-Driven Development?

Your team should be comfortable with Git and modern development practices. TBD thrives in environments with good test coverage and automated CI/CD pipelines, as these systems are crucial for maintaining a stable main branch.

If your organization aims to move towards true continuous integration, TBD can be an excellent catalyst for this transition. However, without a comprehensive suite of automated tests, the risk of introducing bugs into the main branch increases significantly.

If your team doesn't have good automated testing in place, it might be wise to focus on improving this aspect before transitioning to this workflow.

3. What About Feature Flags?

Another key factor is your team's willingness to embrace feature flags. These allow for greater control over feature releases and are often essential in a trunk-based workflow.

Teams that are open to incorporating feature flags into their development process are better positioned to succeed with TBD.

4. How Is Your Product's Release Cycle?

If you're developing applications with inherently slow release cycles, such as mobile apps requiring app store approval, the benefits of TBD may be less pronounced. The rapid integration and deployment capabilities of TBD are most advantageous in environments where frequent releases are possible and desirable.

Transitioning to Trunk-based Development

Transitioning to this new workflow can seem daunting at first. If you decide to give TBD a try, here are some tips to help you get started:

  1. Start Small: Begin with shorter-lived feature branches than you're used to, gradually reducing their lifespan. As your team becomes more comfortable, you can further reduce branch lifespans until you're working directly on the trunk for most changes.
  2. Invest in Automation: As we have discussed, good automated testing is crucial for the success of trunk-based development. Prioritize building a comprehensive suite of unit tests, integration tests, and end-to-end tests, and implement a robust CI pipeline that runs these tests automatically on every commit. This safety net will catch potential issues early, giving your team confidence to integrate changes frequently.
  3. Use Feature Flags: Implement a feature flag system and train your team on how to use it effectively. This approach enables you to decouple code deployment from feature release, giving you more control over your product rollout. They're essential for managing incomplete features in production.
  4. Communicate: Make sure everyone on the team understands the new workflow and its benefits. If needed, hold training sessions to explain the principles and benefits of trunk-based development, the importance of small, frequent commits, and how to use feature flags. Sharing this blog post would be a great starting point! 😉

I advise you to stay patient during the transition period, celebrate small victories, and keep the lines of communication open. With time, your team will likely find that trunk-based development leads to a more efficient, collaborative, and productive development process.

Final Words

As more teams adopt DevOps practices and aim for true Continuous Integration, Trunk-based Development is likely to become even more popular. While it might require some initial adjustment, the benefits of reduced merge conflicts, faster feedback cycles, and more frequent releases will become apparent as your team grows more proficient with this workflow.

If you try this workflow, please let us know how it worked for your team!

We hope you found this post helpful! For more Git tips, don't forget to sign up for our newsletter below and follow Tower on Twitter and LinkedIn! ✌️

]]>
Bruno — An API Client Using Git to Fight for Developer Experience https://www.git-tower.com/blog/bruno-api-client-using-git https://www.git-tower.com/blog/bruno-api-client-using-git Fri, 18 Oct 2024 00:00:00 +0000 EDITOR'S NOTE: Have you ever considered using Git to manage your API Collections? That's exactly what Bruno, an open-source API client, is designed to do!

We reached out to the Bruno team to discuss the benefits of using version control for API collaboration and to learn how to get started with their Git-friendly client.

Over the past decade, we’ve seen countless new and existing technologies make a commitment to improving Developer Experience (DX), and the arrival of AI has changed the way many of us work. However, as new vendors appear to capitalize on the multi-billion dollar DX market, there’s a trend that presents a risk: the use of proprietary storage and collaboration platforms instead of Git.

Git is the staple of any developer’s day and it’s undeniable that removing a version control system from the development cycle causes nothing other than risk, confusion, and friction. In our opinion, Git is the cornerstone of DX.

In this post, we’re going to look at how Bruno, an open-source API client, is breaking the mold and intentionally leveraging Git as the collaboration medium. This approach has quickly skyrocketed adoption to over 200,000 monthly active users.

We’ll walk you through what Bruno is, why this decision was made, some of the core capabilities of the tool, and how to try it out.

What is Bruno?

Well, the better question may be “who is Bruno?”, as both its name and logo reflect Anoop’s (Founder and Creator of Bruno) golden retriever.

Bruno – How it started
Bruno – How it started


That said, Bruno (the one that doesn’t shed or want belly rubs) is an API client that is:

  • Open-source
  • Offline
  • Has no cloud component or data syncing
  • Allows for native integration with any Git provider

Each of these items is both in stark contrast to current available solutions and is unapologetically developer-first.

Why use Git?

This question almost seems silly, but it’s a choice that no other API client has made to date. Although Git is the collaboration and storage mechanism for all other areas of software development, historically, API clients have used cloud workspace constructs similar to Google Drive. Unfortunately, this means that there is a fundamental struggle with versioning, as the collections that test, document, or monitor the API live so far away from the code itself.

Bruno’s architectural difference is that collections are stored locally, directly on your file system. This is what allows any Git provider to ingest the collections, and then you’re able to perform GitOps against the collections as you would anything else.

Most developers are used to exporting their collections and maybe uploading them to Git, so it’s a bit of a mind-blowing reaction realizing that with Bruno, you can push, pull, merge, etc., as you would with any code.

Core Capabilities

Bruno provides the classic features you’d expect from an API client, including the ability to structure API requests, configure necessary authentication methods, and review response data after sending a request.

Running a Request with Bruno


The real beauty comes in when you start working with teammates via Git. Below is an example of how you can import a collection by cloning a Git repo. In this case, we’re using GitHub.

Importing a collection by cloning a Git repo


The ability to create a branch of the repo and then commit a change back to the main repo — all without leaving Bruno’s GUI — is something that has never been present within an API client. This change finally allows API collections to be treated as first-class citizens within a traditional Git process.

Of course, there are a slew of additional improvements beyond your typical API client, such as advanced scripting, the ability to load npm packages directly into a collection, and the capability to navigate or modify code directly — all of which can be synced natively with your repositories.

Try it Out!

As DX gets more confusing through additional collaboration systems and proprietary storage, there are tools like Bruno working hard to flip the script.

Give Bruno a try and join more than 500,000 users committed to using Git for API collection sharing! Since Bruno is open-source, getting started with this tool is effortless — simply head over to the GitHub repo or grab it right from the website!

]]>
How Typefully Uses Tower to Conquer Social Media Publishing https://www.git-tower.com/blog/how-typefully-uses-tower https://www.git-tower.com/blog/how-typefully-uses-tower Wed, 25 Sep 2024 00:00:00 +0000 In the third installment of Tower's Customer Stories, we had the pleasure of speaking with Francesco Di Lorenzo, the co-creator of Typefully. Francesco shared how Tower has played an integral role in their development process over the years and revealed how he uses Git to ship amazing products to the world.

Typefully is used and loved by tens of thousands of users and companies worldwide. It's the brainchild of Francesco Di Lorenzo and his co-founder, Fabrizio Rinaldi, born from a side project that unexpectedly resonated with users as a writing tool for social media.

In 2022, Typefully emerged as a stellar tool for writing and scheduling X/Twitter threads. It has since expanded to support multiple social media platforms, including LinkedIn, Threads, and Mastodon. Typefully now also offers AI assistance to simplify the content creation process, providing suggestions, tweet ideas, and rewrites.

Before launching Typefully, Francesco and Fabrizio created Mailbrew, which consolidates various feeds from different apps and websites into a single daily email. They eventually sold it to Evan Williams, one of Twitter’s original co-founders, to fully commit to Typefully.

Who is Francesco Di Lorenzo?

Francesco is the co-creator of Typefully, a powerful tool for writing and scheduling social media content. Prior to Typefully, he co-founded Mailbrew, a service that centralized various feeds into a single daily email.

The Journey to Git

Francesco's love for computers began in his childhood when his parents brought home their first computer and a 56k modem. “Playing games on it and seeing the internet for the first time, even on that slow of a connection, was a magical moment,” he recalls.

Before discovering Git, Francesco's version control method was rather rudimentary. “I was hosting my code on Dropbox and doing backups by zipping the entire project before making big changes,” he shares. “I remember the anxiety of making sure I didn't overwrite or lose any critical files. In retrospect, that was so cumbersome!”

Git was the first version control system Francesco learned, and it revolutionized his workflow. “Learning Git really unlocked a next level of productivity, even without working in a team (back then), because of how you could easily branch out and try new stuff without messing up your project,” he explains.

While Francesco initially learned Git through the command line interface, he soon recognized the benefits of a graphical user interface (GUI). “The CLI is fine for small commits, but a GUI is extremely helpful when reviewing numerous files or hunks and committing only parts of your work, or doing more complex operations,” he notes.

The CLI is fine for small commits, but a GUI is extremely helpful when reviewing numerous files or hunks and committing only parts of your work, or doing more complex operations

Why Tower?

Francesco has been using Tower for over 7 years. Although he tried other options in the past, he was disappointed by the limited feature sets of other Git clients. “Many of these alternatives felt restrictive, often lacking support for advanced operations or requiring cumbersome workarounds for even simple tasks,” he pointed out.

When asked about why he chose Tower, he emphasizes its powerful feature set and native macOS interface: “Tower is different. It seems to really cover everything, providing comprehensive support for all Git functionalities, from basic commits to intricate branching and merging workflows.”

Tower seems to really cover everything, providing comprehensive support for all Git functionalities

When asked about a particular instance where Tower made his life easier, Francesco couldn't pinpoint a specific story. Instead, he highlighted the everyday benefits: “I just love using it daily. For example, the shortcut ⌘ + Z has saved me multiple times after some risky Git operations or mistakes I’ve made.”

This highlights one of Tower's most appreciated features: the ability to undo any Git operation with a simple keyboard shortcut.

Tower — Undo Anything with CMD+Z (CTRL+Z on Windows)


He also appreciates Tower's frequent updates, which give him confidence that he's using a tool that will continue to evolve and improve for years to come.

Favorite Tower Features

When asked about his favorite Tower features, Francesco highlights two key aspects:

  1. The ability to quickly open Tower from the command line: “I appreciate how I can just type gittower in the CLI and jump into Tower for the current directory to check my changes. Sometimes you do need that extra power.”

  2. The staging area: “I love how easily you can select/discard a subset of changes to commit. This is what keeps me coming back to Tower day in and day out.”

Single-Line and Chunk Staging in Tower

Tower at Typefully

Francesco introduced Tower to his entire team, and the response has been overwhelmingly positive. “All our team is on Tower. I think everyone loved it right away,” he shares!

At Typefully, the development team doesn't follow any specific Git methodology. Instead, they focus on creating small, meaningful pull requests and reviewing all code on GitHub. Recently, they've been experimenting with Stacked Pull Requests, a trend that Tower has embraced with the Tower 12 for Mac release.

Tower 12 — Restack Branch
Tower 12 — Restack Branch


“These days, we are also experimenting with Stacked Pull Requests and love how Tower is embracing this new trend with their newly released features. This new workflow is really improving code review for us when paired with feature flags in production for Typefully,” Francesco explains.

We are experimenting with Stacked Pull Requests and love how Tower is embracing this new trend with their newly released features

The team at Typefully makes small pull requests, stacks them on top of each other, and merges often. “Gone are the days of 1000+ lines pull requests that added the entirety of a feature in a single pull request,” Francesco reflects, clearly relieved.

We're grateful to Francesco for sharing his experience with Tower and providing valuable feedback. It's stories like these that drive us to continually improve and expand Tower's capabilities, ensuring it remains the go-to Git client for developers around the world!

Not a Tower user yet?

Download our 30-day free trial and experience a better way to work with Git!

Tower app icon
]]>
Tuple - a Developer’s Guide to Remote Collaboration https://www.git-tower.com/blog/tuple-guide-to-remote-collaboration https://www.git-tower.com/blog/tuple-guide-to-remote-collaboration Mon, 16 Sep 2024 00:00:00 +0000 Git is the backbone of collaboration for developers. Without a solid version control system, working together is an uphill battle. Many developers turn to Tower for its powerful suite of collaboration features. However, using Git - or even a tool like Tower - is just one part of the equation. The real magic happens when you combine the right tools with the right techniques. That’s where pair programming comes in.

In this post, we’ll define pair programming, explore its benefits, provide tips for getting started, and discuss the challenges of pairing remotely. Finally, we’ll show how Tuple makes remote pairing not just possible, but a joy for tens of thousands of developers.

What is Pair Programming?

Pair programming means different things to different people, but it always boils down to two developers working together on the same code. The two most common pairing techniques are Driver/Navigator and Ping Pong.

Driver/Navigator: The driver types the code and stays focused on the current task, while the navigator thinks ahead, ponders edge cases, spots bugs, suggests refactorings, asks good questions, and stays zoomed out.

Ping Pong: Great for test-driven development (TDD), the workflow loops as follows:

  1. Person 1 writes a failing test.
  2. Person 2 makes it pass.
  3. Person 2 writes a failing test.
  4. Person 1 makes it pass.

This approach naturally divides the work and keeps both developers engaged without the need to frequently swap drivers. Here, two keyboards are handy, or a remote pairing app like Tuple.

Pro Tips for Ping Pong Pairing:

  1. Don’t stress about uneven typing time - it balances out as you switch roles.
  2. Focus on writing minimal failing tests and the simplest code to pass them.
  3. Always take time to refactor when all tests are passing.

These styles might sound formal, but we believe pair programming can be as casual as asking, “Hey Jess, you wrote this code - can you help me make these changes?” or “Hey Steve, I’m stuck on something. Can you take a look and help me think it through?” As long as two developers are working together on the same problem, that’s pairing.

The Case for Pair Programming

Is pair programming worth it? We think so. Pairing brings more brainpower to the table, which means catching bugs early, finding more creative solutions, and maintaining higher code quality. With someone watching, you’re less likely to cut corners or get distracted. This investment in better code pays off with a healthier codebase, making future development faster and smoother. Plus, when two people are deeply familiar with the code, you reduce the bus factor - the risk of losing critical knowledge if someone is unavailable.

Research backs this up: studies show that for a development-time increase of around 15%, pair programming improves design quality, reduces defects, lowers staffing risk, enhances technical skills, boosts team communication, and is more enjoyable. Another study found that paired teams completed tasks 40% faster than individuals.

As pairing gained popularity, variations emerged, including mob programming or ensemble programming. These terms are interchangeable, and like our definition of pairing, we like to keep it simple: mob or ensemble programming is when three or more developers work together on the same code.

In short, these practices can:

  1. Make tough problems easier to solve.
  2. Improve code quality and reduce bugs.
  3. Spread knowledge across your team.
  4. Increase developer satisfaction.

Tips for Getting Started

While the benefits of pair programming are well documented, getting started can be daunting. It’s a skill, and like any skill, it takes time to master. That’s why we created our Pair Programming Guide. Here are our three top tips to help ease the transition:

  1. Pick a comfortable partner: Start with someone you already work well with. Pairing involves sharing work-in-progress, which can feel vulnerable. A familiar face helps ease the nerves.
  2. Make it fun: Choose areas of the codebase you enjoy working on. Pairing should be enjoyable, especially at first when you’re still getting the hang of it.
  3. Start small. Begin with short sessions - an hour or two max. Use a timer to break up that time together. "Hey I know we blocked 2 hours to work on this together. Mind if we set a 50m timer, take a 10m break, and then wrap up for the last hour?" It'll feel less exhausting with a built-in break, especially if you both know it’s coming.

The Remote Challenge

Pair programming originated in the days of in-person work, where it was easy to share a screen, switch roles, or sketch out ideas on a whiteboard. You could glance over to see if a colleague was free before asking for help. But as the software world shifted toward remote work, spontaneous, side-by-side collaboration became harder to replicate. Working from home introduced friction - suddenly, it wasn’t as easy to ask for help or collaborate in real-time.

Enter Tuple

Before COVID and the mass transition to remote work, Tuple’s founders left their cushy dev jobs to solve this very problem. They wanted to build a tool that could bring the magic of in-person pairing to the remote world. Existing tools like Zoom or Slack had screen sharing, but they weren’t designed for the specific needs of developers. Switching who was driving felt clunky. It was hard to point out specific lines of code in a crowded IDE, and sketching out designs or even just reading the code on a low-resolution, high-latency connection was a struggle. And unlike an office, you couldn’t just tap someone on the shoulder for a quick assist.

So, they built Tuple - a screen sharing and remote control app designed from the ground up for developers. Tuple makes you feel like you’re sitting right next to your pair, even when you’re miles apart. It has features you won’t find in generic screen sharing tools: seamless driver switching, shared control by default, built-in annotations for pointing things out, and even whiteboarding. Tuple prioritizes screen share quality over webcams, ensuring that tiny lines of code are crystal clear. Plus, Tuple is native on both macOS and Windows, using a cross-platform engine written in C++ to optimize performance and keep CPU usage low - perfect for compiling builds and running tests.

Tuple in action!

Picture this: you’re working on something tricky and need help. You hop on a call, pull up your IDE, and start talking through the problem with a pair. But with 50 lines of barely legible code on the screen, your pair is lost. A few frustrating seconds later, maybe 10, you’re finally on the same page, but the flow is gone.

Not with Tuple. With one click, you switch to annotation mode, circle what you’re talking about, and your pair digs in. They’ve got an idea - mind if I try something? With a single click, they take control, type it out, and you run the test. It passes. The flow is preserved, and a solution is found.

That’s what Tuple is about: making pairing easy, effective, and fun. It tackles the challenges of remote work and delivers an experience that feels as close to in-person collaboration as possible. Whether you’re into formal pair programming or just need to collaborate in real time, Tuple is the tool to make it happen.

Ready to see for yourself? Try Tuple free for two weeks - no credit card required.

]]>
Mastering Raycast (for Developers!) https://www.git-tower.com/blog/mastering-raycast https://www.git-tower.com/blog/mastering-raycast Fri, 06 Sep 2024 00:00:00 +0000 If you’ve spent more than just a few minutes playing around with Raycast, you’ve certainly realized that it’s much more than a simple application launcher. Its extensive range of productivity tools can greatly improve the way you work on a Mac.

However, If you’ve recently joined the Raycast community, you might find it a bit overwhelming to learn about all its features. This is where this article comes in!

In this guide, we’ll cover everything you need to know about how Raycast can transform your experience as a developer. From its core functionalities to extensions, themes, and unique commands, we’ve got it all covered!

☝️ While Raycast offers a lot for free, there is also a PRO plan available with additional features. The Raycast team was kind enough to provide an exclusive coupon for Tower readers: use the code TOWERFRIENDS for a one-off 30% discount on the Pro Plan!

1. The Basics

When used to its full extent, Raycast has the potential to render many of your small utility apps obsolete. Let’s explore everything Raycast has to offer and how useful it can be for productive work on macOS.

1. Setting Hotkeys to Launch Apps

The most obvious use case for Raycast is launching applications. While you can easily open Raycast using the hotkey specified in the Settings and start typing, there are more efficient methods available.

You can assign specific hotkeys to your most frequently used applications for instant access. Even better, these hotkeys can also allow you to cycle through your open apps! This is much more effective than repeatedly pressing ⌘ + TAB until you locate the app you want.

Setting up these hotkeys in Raycast is easy. Start by typing the name of the application you're looking for, hit ⌘ + K to bring up the list of available actions, and select "Configure Application."

Raycast – Configure Application
Raycast – Configure Application


From there, click "Record Hotkey" to assign your preferred hotkey for the application.

Raycast – Record Hotkey
Raycast – Record Hotkey


I am a big fan of using the Hyper Key in these situations. You can learn more about the powerful Hyper Key in our Mastering the Keyboard article, but in short, it involves remapping a key (most commonly the CAPS LOCK key) to serve as a combination of all standard modifiers (⌃ + ⌥ + ⌘ + ⇧). This minimizes the risk of using conflicting key combinations.

As a developer, it makes sense to set up custom hotkeys for your essential applications, which likely include your code editor, terminal, browser, and Git client!

Here are some of my most frequently used hotkeys:

  • ⌃⌥⌘⇧ + S - Launches Safari
  • ⌃⌥⌘⇧ + G - Launches Tower
  • ⌃⌥⌘⇧ + T - Launches Warp
  • ⌃⌥⌘⇧ + C - Launches VS Code
  • ⌃⌥⌘⇧ + E - Launches Sublime Text
  • ⌃⌥⌘⇧ + F - Launches Firefox Developer Edition

This functionality extends beyond just launching applications. In Raycast, you can set up hotkeys for specific commands, such as toggling between light and dark modes or quickly locking your screen when stepping away from the keyboard.

I recommend taking a look at the list of available commands and gradually adding new hotkeys for the commands you use frequently, so that you don't feel overwhelmed. This is one of my favorite features of Raycast!

Quicklinks

On this topic, the "Quicklinks" feature also deserves a mention. It allows you to launch specific files, directories, or URLs, making it particularly useful for coding projects!

Raycast offers a library of suggestions, such as searching directly on Stack Overflow and YouTube. You can also easily add frequently visited URLs (like localhost:3000) or project folders to jump straight into your work.

Raycast – Create Quicklink
Raycast – Create Quicklink


Like other applications and commands, you can also assign hotkeys to the Quicklinks you create.

2. Text Snippets

We've mentioned the importance of using text snippets before. Text snippets are an excellent way to speed up repetitive tasks, such as filling out forms, typing frequently accessed links, or inserting boilerplate code.

Raycast makes it easy to create new text snippets, offering powerful features like Dynamic Placeholders. These allow you to incorporate custom information from your clipboard or today’s date. You can even specify where your cursor should be located after the text is inserted!

Raycast — Create Snippet
Raycast — Create Snippet


You can also share these snippets with your organization, which is a great way to ensure consistency when answering support questions or writing documentation.

The Raycast team provided a long list of snippets you can use as suggestions — including some you can use for coding. When you find a snippet you like, simply click the "Add to Raycast" button to add it to your collection.

Raycast — Snippet Explorer
Raycast — Snippet Explorer

Not a Tower user yet?

Download our 30-day free trial and experience a better way to work with Git!

Tower app icon

3. Clipboard History

The "Clipboard History" feature allows you to quickly retrieve items that you have previously copied to your clipboard. In a way, it's a great companion to the "Text Snippets" feature, as it can significantly speed up your typing sessions.

Compared to other clipboard managers, Raycast has a couple of aces up its sleeve, like its filtering capabilities. To find the snippet you're looking for, you can filter by content type — such as text, images, links, files, or colors — or by simply typing a portion of the entry.

Raycast also provides useful information, such as the character count and word count, as well as the source application from which the content was originally copied.

Raycast – Clipboard History
Raycast – Clipboard History

4. Arrange Windows

Window management is an area where macOS tends to fall short. Fortunately, Raycast offers a wide range of options to quickly position application windows exactly how you want them.

I recommend typing wm to view a list of all available options, and then setting up hotkeys for your most frequently used functions.

Raycast – Window Management
Raycast – Window Management


If you're a web developer, you'll likely want to have your text editor on one side and the browser on the other. Personally, I also enjoy maximizing my windows from time to time.

Here are the hotkeys I've set up for these actions:

  • ⌥⌘ + ← - Left Half of the Screen
  • ⌥⌘ + → - Right Half of the Screen
  • ⌥⌘ + ↑ - Maximize

The PRO version of Raycast offers Advanced Window Management capabilities, allowing you to create custom workflows. These workflows support multiple monitors and Quicklinks, so that you can open files or links instantly.

For example, you can set up a "coding" workflow with the following:

  • Text Editor with a specific project open on the left half of the screen.
  • Web Browser with a specific URL on the right half of the screen.
  • Terminal maximized on your secondary display.

5. Calculator

Raycast features a powerful calculator that allows you to perform a wide range of calculations, including:

  • Unit conversions
  • Timezone adjustments
  • Currency conversions (including cryptocurrencies)

You can use the calculator for various mathematical operations, such as calculating the square root of a number, converting rem to pixels, or converting colors from hex to RGB.

Raycast – Calculator
Raycast – Calculator


The best way to become familiar with the calculator is to try calculating something and see if it works. Chances are, it will perform just as you would expect!

6. Meetings

Not sure when your next meeting is? Use the My Schedule command to check your agenda, block off focus time, email attendees, or copy event details. You can also use this panel to join conference calls directly within Raycast.

No conversation about meetings would be complete without mentioning the Open Camera command. Before joining a meeting, I usually run this command to preview my setup before joining a video call. It can be quite handy!

Raycast – Open Camera
Raycast – Open Camera

7. Ask AI

The PRO version of Raycast features seamless AI integration, allowing you to interact with multiple large language models. It supports popular solutions like ChatGPT and Claude 3, as well as open-source alternatives such as Mistral/Mixtral and Meta's Llama.

You can use these chatbots directly within Raycast or run AI-specific commands on highlighted portions of text. This allows you to proofread text, change its tone, or explain code step by step. It even supports attachments and image generation!

If you frequently use the same prompts, I recommend creating specific AI Commands with tailored instructions to automate those tasks. For inspiration, the Raycast team has a Prompts Explorer and a Presets Explorer, which offer excellent suggestions for coding to help you get started.

Raycast – Prompt Explorer
Raycast – Prompt Explorer

2. Extensions

While the basic version of Raycast already includes a wide range of productivity tools, one of its superpowers is the abundance of extensions available in the Raycast Store.

In this section, we'll have a look at some of the best Raycast extensions for developers.

Tower

One of the great things about Raycast's store is that anyone can contribute. A big shoutout to Thomas van der Westen for creating this Tower extension, which allows you to quickly open your Git repositories in Tower!

Raycast – Tower Extension
Raycast – Tower Extension

VS Code

If you're a Visual Studio Code user, you'll definitely enjoy this one! It not only lets you navigate to recent projects, but also install extensions from the VS Code Marketplace and access the commands available in the editor's Command Palette.

Raycast – VS Code Extension
Raycast – VS Code Extension

Tailwind CSS

A must for Tailwind users. This extension enables you to search through Tailwind's documentation, utility classes, color palettes, and Tailwind UI components.

Raycast – Tailwind Extension
Raycast – Tailwind Extension

Terminal Extensions

Raycast offers extensions that allow you to quickly launch new tabs and windows on any popular terminal application, such as:

Naturally, there is one for macOS's default terminal as well!

Homebrew

I always rely on Homebrew to install new applications on my Mac. This extension makes installing, upgrading, and searching for new formulas and casks a breeze!

Raycast – Homebrew Extension
Raycast – Homebrew Extension

Manage Issues

To create, search, and modify issues, among other tasks (such as navigating to projects), you can install the extension of your service of choice:

For Design Work

Many of us work with colors, convert image formats, and measure pixels in our daily tasks. There is a plethora of useful extensions available for nearly any need in this area.

Here are some of my favorites:

  • Ruler: This extension enables you to measure distances on your screen.
  • Color Picker and ColorSlurp: These tools help you pick colors, work with color palettes, check contrast, and convert between various color formats.
  • Image Modification: This extension allows you to convert between different image formats, compress images, and apply simple transformations, such as rotation or resizing.
Raycast – Color Picker Extension
Raycast – Color Picker Extension


Finally, the ray.so extension deserves a special mention for those moments when you want to create stunning images of your code!

3. Fun

In our "10% More Productive" series, we always like to highlight some customization options and other fun topics. Raycast has many Easter eggs that you can use while your project is being built or deployed to the cloud.

Here are some of the most popular ones…

Confetti

The Confetti command, as the name implies, fills your screen with confetti! It's perfect for celebrating those special moments, like when you've successfully fixed a tricky bug or centered that <div>!

Raycast – Confetti
Raycast – Confetti

Emoji Picker

You can use Raycast to quickly find the perfect emoji to express yourself — whether you’re on Slack or in Git!

The app offers a complete emoji picker, but you can also simply type the emoji you’re looking for directly in the Raycast main window, like :tada:

Raycast – Emoji Picker
Raycast – Emoji Picker

Typing Practice

How many WPM (Words Per Minute) can you type? Run Raycast's Typing Practice command to find out!

This is a fun challenge to participate in with fellow developers. Here's what I got after 3 attempts (promise!) ☺️

Raycast – Typing Practice
Raycast – Typing Practice

Themes

Just like your favorite code editor or terminal, the PRO version of Raycast also offers a variety of themes to further customize your Raycast window.

You'll find many popular developer themes available, including Solarized, Atom, Cobalt 2, and Dracula. Check out Raycast's Theme Gallery for the complete list!


Final Words

While it may seem deceptively simple, Raycast can be an extraordinarily powerful tool! With its many commands, extensions, and features, a little time and curiosity can significantly boost your productivity. By following the recommendations provided here, I am confident you will become a more productive developer in no time!

Don't forget that you can use the code TOWERFRIENDS for a one-off 30% discount on Raycast's Pro Plan!

We hope you find this collection of tips both useful and inspiring. For more tips and tricks, don't forget to sign up for our newsletter below and follow Tower on Twitter and LinkedIn.

]]>
Mastering Tower (Windows Edition) https://www.git-tower.com/blog/mastering-tower-windows https://www.git-tower.com/blog/mastering-tower-windows Mon, 02 Sep 2024 00:00:00 +0000 Following the success of our Mastering Tower for Mac guide, it's time to give Tower for Windows some love! In this page, we will show you how to get the most out of your favorite Git client. From navigation tips to workflow hacks, you'll find everything you need right here! 🔥

Fasten your seatbelt and prepare to boost your productivity while working with Tower! Whether you're a seasoned user or just starting out, we’re confident that this guide will introduce you to many tips and tricks that you may not yet be aware of.

Let’s dive right in!

☝️ Tower is available for both Windows and Mac. If you haven't installed our Git client yet, you can download our 30-day FREE Trial.

1. Navigation Tips

Like any tool designed for productivity, Tower offers a variety of keyboard shortcuts (and we all love keeping our hands on the keyboard, don’t we?).

By remembering a few key shortcuts, you can navigate between projects and views much more quickly. Let's have a look at the most important ones!

BTW: for your convenience, you can download our Tower Cheat Sheet, available for both Windows and Mac.

Tower cheat sheet
Tower cheat sheet

Quick Open

To quickly access any repository, press CTRL + O to open Tower's "Quick Open" window.

When the input field is empty, the repositories will be organized based on the last date they were accessed. Just begin typing to locate the project you want.

Quick Open in Tower for Windows
Quick Open in Tower for Windows


Tower regularly scans your local disks for available Git repositories, including those you haven’t opened before. This is the default setting, but you can disable it by going to the "General" tab in the "Preferences" window.

Switching Between Views Using Keyboard Shortcuts

Once you've opened a project, you can swiftly switch to a different view using the following keyboard shortcuts:

  • Press CTRL + 1 to access the "Working Copy" view.
  • Press CTRL + 2 to access the "History" view.
  • Press CTRL + 3 to access the "Stashes" view.
  • Press CTRL + 4 to access the "Pull Request" view.
  • Press CTRL + 5 to access the "Reflog" view (this shortcut works even if the "Show Reflog in sidebar" option is disabled in the Preferences).

You can press CTRL + 0 to navigate to the HEAD branch.

Additionally, you can easily switch between the "Services" and "Repositories" views by pressing ALT + S and ALT + R.

Switching Between Views Using Keyboard Shortcuts in Tower for Windows

Quick Actions

"Quick Actions" is Tower's version of the Command Palette. It’s so powerful that we've dedicated an entire blog post to it!

Within a project, simply press ALT + ⇧ + A to launch Quick Actions and begin typing; the suggested actions will be based on the context.

Here are some powerful actions you can perform:

  • Look for a file.
  • Change themes.
  • Check out branches or tags.
  • Configure a different Committer Identity.
Quick Actions in Tower for Windows
Quick Actions in Tower for Windows

2. Staging and Committing Tips

To stage the currently selected file, press the SPACEBAR. To stage all recent changes, use CTRL + ⇧ + A (you can reverse this action with ALT + CTRL + ⇧ + A). To discard all local changes, CTRL + ⇧ + ⌫ is your friend.

In the "Working Copy" view, press CTRL + ⇧ + C to quickly bring up the commit dialog. Need assistance in crafting a better commit message? Tower is here to help!

You can use the following shortcuts:

  • \ to insert a file name.
  • c: to reference a commit.
  • # to mention an issue (including keywords like "closes/fixes/resolves"), as long as you've set up a Services account in Tower.

If that seems too much to remember, no need to worry! Just type / in the "Commit Subject" field, and a list of relevant commands will show up.

Writing Better Commit Messages in Tower for Windows
Writing Better Commit Messages in Tower for Windows


Once you’ve completed the subject of your commit message, you can simply press to move to the "Body" field.

Not a Tower user yet?

Download our 30-day free trial and experience a better way to work with Git!

Tower app icon

3. Workflow Tips

Drag and Drop

Let’s take a break from the keyboard and shift our focus to the mouse for a bit. We’re going to look into a favorite feature among many Tower users: the drag and drop functionality!

Creating a New Branch or Tag

You can create a new branch or tag based on a specific commit by dragging and dropping a commit item onto the "Tags" or "Branches" sections in the sidebar.

Additionally, in Tower's sidebar, you can drag a branch and drop it onto the "Branches" section to generate a new branch from the one you dragged.

Creating a New Branch or Tag with Drag and Drop in Tower for Windows

Pulling, Pushing, Merging, Rebasing, and Branch Tracking

By dragging one branch onto another, you can pull, push, publish, merge, rebase, or track a branch. Press and hold the Alt key before you start dragging to unlock additional operations.

Publishing, Pushing, Merging, and Rebasing a Branch with Drag and Drop in Tower for Windows

Cherry-Picking

Just like the earlier tip, you can cherry-pick a commit by dragging it from the "History" view to the "Working Copy" item in the sidebar or directly to the HEAD branch.

Cherry-Picking in Tower for Windows

Moving a Commit

In the "History" view, you can easily move a commit by dragging and dropping it. Keep in mind that this action will rewrite your commit history.

Moving a Commit in Tower for Windows

Squashing

To combine multiple commits into a single one, simply click and drag one commit onto another (you will see a "+" symbol). This will aggregate all file modifications into the latter.

When squashing, all commit messages are preserved and combined; however, if you prefer to keep only the original message, hold down the Alt key before dragging to fixup commits instead.

Squash and Fixup in Tower for Windows


You can also start your commit message with "squash!" or "fixup!" followed by an existing commit.

After adding that commit, navigate to your HEAD branch's history, where you will find a yellow banner at the top to complete the process.

Autosquashing in Tower for Windows


💡 As mentioned earlier, this action will alter history, resulting in a new commit. It's advisable to perform this action in your local repository only, before pushing your changes.

Chunk and Line Staging

In Tower, you have the option to choose specific chunks or even individual lines that you want to commit. If you prefer smaller, detailed commits (which is definitely a good practice!), this powerful feature will be invaluable.

Just click on the lines (or chunks) you want to include in the next commit. You can then review what is staged or unstaged before finalizing the commit.

Line Staging in Tower for Windows

Undo

In Tower, most actions can be undone by pressing a very familiar keyboard shortcut: CTRL + Z.

As a general rule, try using this combination to reverse any unwanted actions (like a commit, merge, chunk discard, or branch deletion); it should just work as you'd expect! If you need to redo the action, you can do so by pressing ⇧ + CTRL + Z.

Undoing and Redoing a Merge in Tower for Windows

Mark as Assume Unchanged

Suppose you need to make modifications to a file locally but don’t wish to commit these changes to the repository. How do you handle this?

If the files are untracked, you can simply ignore or exclude them. However, in this situation, we want to ignore the local changes. To do this, you should use the "Mark as Assume Unchanged" feature.

To apply this, just right-click the file and choose "Mark > Set Assume Unchanged." That’s it!

"Set Assume Unchanged" in Tower for Windows


If you later decide to modify this setting, you can easily undo it by pressing CTRL + Z. However, since you might want to adjust this setting again in the future, you can ask Tower to "Show Assume-Unchanged" items by clicking the "Additional View Options" button, as highlighted in the screenshot below:

Showing
Showing "Assume-Unchanged" Items

"Working Copy" View Modes

Now is a good opportunity to remind you that Tower offers different "Working Copy" view modes!

By default, Tower displays only the modified files in a list format, but you can view all your project files by selecting "View as Tree" and then "Show Non-Modified Items."

It is quite useful when you need a comprehensive overview of your project's files!

"Working Copy" View Modes in Tower for Windows

Accessing File History (and Restoring Previous File Versions)

You can combine the previous tip with this one to quickly review how a file has changed over time or to revert to a prior version.

Right-click on any file and choose "Show File History" to see all the commits that have affected that specific file. Once you find the commit that interests you, right-click on it and select "Restore [FILE] at Revision [REVISION]" to bring that version back into your working copy.

Keep in mind that this action will overwrite any existing local changes to those files!

Alternatively, you can click on "Export [FILE] at Revision [REVISION]" to download a ZIP file containing that version of the file (or the complete file tree from that revision, as shown below).

Restoring Previous File Versions in Tower for Windows

Stashing

Stashing is a crucial action to take when you need to save your uncommitted changes and leave your working directory clean — for instance, if you need to pull updates to the branch or switch to a different branch.

You can stash your work by pressing CTRL + S. To apply your stashed changes, use CTRL + ⇧ + S. If you find yourself frequently stashing and applying your changes right after, consider using Tower's "Snapshot" command instead: it saves a copy of your current working copy's state and immediately applies it, allowing you to maintain your momentum.

Snapshots can also be found in the "Stashes" view, alongside your other stashes. You can easily create a snapshot of your entire working copy by right-clicking on the "Working Copy" view and selecting "Create Snapshot...".

Creating a Snapshot in Tower for Windows
Creating a Snapshot in Tower for Windows


Alternatively, you can stash (or create a snapshot of) a single file by right-clicking on it in the working copy view and selecting the appropriate option:

Snapshotting a single file in Tower for Windows
Snapshotting a single file in Tower for Windows


If you try to switch branches while your repository is dirty, Tower will prompt you to stash your files. If you want to carry your changes over to the new branch, check the "Re-apply Changes After Operation is Finished" box — this will automatically stash your changes, switch branches, and then apply those changes (similar to the git switch command).

Stash Current Local Changes in Tower for Windows
Stash Current Local Changes in Tower for Windows

Rebase Onto

The "Rebase Onto" command is useful when you want to take all the commits from the current HEAD branch that aren't present in the current base branch and apply them to a new base branch. This is typically used when you wish to change the base of a feature branch to another branch.

You can perform this action by right-clicking the HEAD branch and selecting "Rebase Onto Revision…".

Rebase Onto in Tower for Windows
Rebase Onto in Tower for Windows

4. Settings to Tweak

Setting a Default Cloning Directory

Do you frequently clone repositories? Make sure you're cloning them to the correct folder!

Navigate to the "General" tab in the Preferences window to specify your default directory for cloned repositories.

Default directory for cloned repositories in Tower for Windows
Default directory for cloned repositories in Tower for Windows

Automatic Signing of Commits and Tags (GPG and SSH)

Tower offers integrated support for GPG and SSH, enabling it to automatically sign your new commits. This feature extends to other actions like merging and cherry-picking as well.

You can apply this setting globally by going to the "Git Config" tab in the Preferences, or you can restrict it to specific Git repositories by accessing the "Settings" view in the sidebar.

Automatic Signing of Commits and Tags in Tower for Windows
Automatic Signing of Commits and Tags in Tower for Windows


Additionally, you can easily sign tags automatically by ticking the checkbox in the "Create New Tag" dialog.

Changing Author Profiles

To conveniently alternate between different identities when making commits, you can create multiple user profiles in Tower's "User Profiles" section within the Preferences window. It's also possible to assign distinct GPG or SSH keys for each profile.

Author Profiles in Tower for Windows
Author Profiles in Tower for Windows


You can switch identities prior to committing in the "Working Copy" view, or set the default identity for that particular repository in the "Settings" view.

5. Powerful Features (That You May Not Be Aware Of)

Image Diffing

Tower comes with a built-in "Image Diffing" feature that accommodates all the most widely used file formats, including PNG, JPG, GIF, BMP, TIFF, and JPEG2000.

I found this feature particularly valuable when I optimized hundreds of images and wanted to review the outcome by comparing the original and compressed images (along with their file sizes) side by side.

It's also extremely useful during rebranding efforts!

Image Diffing in Tower for Windows
Image Diffing in Tower for Windows

Advanced Filtering

Our "Search" function allows you to filter commits by Author, Date, Message, Commit Hash, or File. However, did you realize that you can combine these search criteria?

This is incredibly useful when you need to find commits from a coworker within a specific time period!

Advanced Filtering in Tower for Windows

Final Words

You've made it to the finish line! Congrats: you're now a Tower for Windows ninja! 🥷

I hope you found this guide useful! If you're interested in learning more, check out our documentation; we cover not only Tower but also Git and version control.

To stay updated on Tower and get additional programming tips, be sure to follow our blog, subscribe to our newsletter below, or connect with us on on X/Twitter and LinkedIn! ✌️

]]>
Beyond “Commit” and “Push”: 5 Advanced Git Features You Should Know https://www.git-tower.com/blog/5-advanced-git-features https://www.git-tower.com/blog/5-advanced-git-features Wed, 31 Jul 2024 00:00:00 +0000 Many developers work with Git every day, adding commits, creating branches, and pushing or pulling the latest changes. However, Git offers a wide range of advanced features beyond these basics that few developers know about.

Let's change that!

Today, we will explore five of Git's hidden gems. These advanced features, often overlooked by even seasoned developers, showcase the depth and flexibility of Git.

We will cover:

  1. Git Bisect
  2. Git Rerere
  3. Git Attributes
  4. Git Notes
  5. Git Worktree

Whether you're a solo developer or part of a large team, understanding and leveraging these features can take your version control game to the next level.

Hop on board the Git train! 🚂

1. Git Bisect

Git Bisect is a powerful debugging tool that helps you pinpoint the exact commit that introduced a bug in your project. This feature is a great example of how Git can be much more than just a version control system, offering valuable debugging capabilities as well!

Imagine you discover a bug in your current version, but you know it was working fine 3 months ago. Instead of manually checking every commit from the last 3 months, you can use Git Bisect to quickly narrow down to the exact commit that introduced the issue, potentially saving hours of debugging time.

This command uses a binary search algorithm to efficiently narrow down the problematic commit, which can be incredibly useful when dealing with large codebases or long periods between discovering a bug and its introduction.

Here's how it works:

  • First, you need to inform Git of a commit where the code is working correctly (the "good" commit) and another commit where the bug is present (the "bad" commit).
  • Git then selects a commit that lies halfway between the two points you provided and prompts you to confirm whether the bug is present in that commit.
  • This iterative process continues as Git narrows down the range of commits until it pinpoints the exact commit that introduced the bug.

Here's how you can get started with Git Bisect:

$ git bisect start
$ git bisect bad  # Current version is "bad"
$ git bisect good <good-commit-hash> # Commit that is known to be "good"
# Git then checks out a commit for you to test and you mark it as "good" or "bad"
$ git bisect good  # or git bisect bad, depending on your conclusion
# Repeat until Git identifies the problematic commit
$ git bisect reset  # to end the bisect session

Git Bisect offers a visualization option that can be quite handy. You can use git bisect visualize to display a graphical representation of the commit history being analyzed.

You could also write a script to automatically test each commit, for even faster debugging. You would then execute it by typing git bisect run ./script.sh.

Git Bisect offers a wide range of powerful subcommands. You can explore the complete list of features here.

2. Git Rerere

The name "Rerere" might make you chuckle, but if you find yourself dealing with the same Git conflicts often, you will love this feature!

Rerere stands for "Reuse Recorded Resolution"; as the name suggests, it allows Git to remember how you've resolved a merge conflict so that it can automatically resolve it the same way if it encounters the same conflict again.

This is particularly useful when working with long-lived topic branches, as you may encounter the same conflicts repeatedly.

To enable rerere, you'll just need to type the following:

$ git config --global rerere.enabled true

Once enabled, Git will automatically record how you resolve conflicts and reuse these resolutions in future conflicts.

This command is usually run without arguments or user intervention, but you can learn more about Git Rerere here.

Not a Tower user yet?

Download our 30-day free trial and experience a better way to work with Git!

Tower app icon


3. Git Attributes

Git Attributes enable you to define attributes for paths within your repository. These attributes can control Git's behavior for specific files or directories. They're especially useful in projects with mixed file types, cross-platform development, or when certain files require specific handling.

They allow you to customize Git's behavior on a per-repository or even per-file basis. These attributes are defined in a .gitattributes file that you can add to the root of your repository.

This feature can be quite useful in a couple of scenarios. Firstly, it allows you to specify to Git which files should be treated as binary data. For example, certain text files (such as those ending in .pbxproj from Xcode projects) should be treated this way because their changes cannot be merged, and viewing the differences is not really helpful.

To instruct Git to recognize all .pbxproj files as binary data, you can include the following line in your .gitattributes file:

*.pbxproj binary

You can also use this feature to compare binary files, such as Microsoft Word documents! You can use the diff key attribute like in the following example:

*.docx diff=word

This command instructs Git to apply the "word" filter to any file matching the .docx pattern when reviewing a diff with changes. The "word" filter needs to be set up by downloading and installing a program like docx2txt, that can convert Word documents to text files for accurate diff comparison.

Finally, you can also use the merge key attribute to use different merge strategies for specific files in your project. This is quite helpful when you want to merge a branch ignoring certain files, such as a database file.

You can add the following line to the .gitattributes file:

*.db merge=ours

And then define a dummy ours merge strategy with:

$ git config --global merge.ours.driver true

In this scenario, database.db will remain at its original version.

A lot more could be written about .gitattributes, so we encourage you to check its documentation here.

4. Git Notes

Git Notes enable you to add or inspect notes on objects. Think of these notes as comments that you can associate with objects (usually commits) without changing the object itself.

These notes can be helpful for code reviews, providing context to automated processes, or as reminders for yourself or your team.

To add a note to the current commit, type the command below:

$ git notes add -m "This is a note"

The command above will work for the current commit, but you can also add a commit hash to reference a specific one.

To edit or remove a note, you can use:

$ git notes edit <commit-hash>
$ git notes remove <commit-hash>

You can view a commit's notes by typing:

$ git notes show <commit-hash>

You can learn more about this command here.

5. Git Worktree

Git Worktree is a useful feature for developers who frequently switch contexts between different parts of a project or need to perform parallel operations on different branches.

It allows you to work on multiple branches simultaneously without stashing or committing partial work. Git Worktree also makes it easy for you to build or test different versions of your project concurrently and perform long-running operations on one branch while working on another.

Let's imagine you are working on a feature branch, and suddenly a critical bug is reported on the main branch. With worktrees, you can:

  1. Add a new worktree for the main branch.
  2. Navigate to the new worktree and fix the bug.
  3. Commit and push the fix from the hotfix worktree.
  4. Return to your original worktree and continue working on your feature.

Before we see how to get started, here are some considerations to keep in mind:

  • Changes in one working tree don't affect others until they're committed and pulled.
  • It is not possible to have multiple worktrees on the same branch (each worktree can be on a different branch).
  • If you are dealing with a very large repository, be cautious of the amount of disk space being used (although all worktrees share the same .git directory to save disk space).

Now, onto the fun part!

Git worktree offers two main ways to create a new working tree:

  1. Creating a new branch: When you use git worktree add <path> without specifying a branch, Git does two things:
  • It creates a new branch named after the last part of the path you provided.
  • It checks out this new branch in the new worktree at the specified path.

Consider the following example:

$ git worktree add ../hotfix

This command creates a new branch called "hotfix" and sets up a new worktree for it in the "../hotfix" directory.

  1. Using an existing branch: If you want to work on an already existing branch in a new worktree, you can specify both the path and the branch name:
$ git worktree add <path> <branch>

Here's an example:

$ git worktree add ../feature-work existing-feature-branch

This creates a new worktree in the "../feature-work" directory, with the "existing-feature-branch" checked out.

These options give you flexibility in setting up new working areas, whether you're starting a new task or continuing work on an existing branch.

You can list all the worktrees you have created by typing:

$ git worktree list

Finally, to remove a worktree, you can use:

$ git worktree remove path/to/worktree

Git Worktree can be quite a complex command, as it offers many features. You can check the full documentation here.

Final Words

As you can see, there's a lot more to Git than just committing, pushing, and pulling! Git can be much more than just a version control system, and the advanced features we presented bring unique capabilities to the table, enhancing everything from debugging and conflict resolution to workflow customization and project organization.

With Git, there's always something new to learn — mastering it is a continuous journey. By familiarizing yourself with these lesser-known features, you will become a more proficient and versatile developer. Give them a try!

For more programming tips (not just about Version Control), don't forget to sign up for our newsletter below and follow Tower on Twitter and LinkedIn! ✌️

]]>