Seeking the thrill of transformative tech? Explore the art of designing and implementing DevOps solutions on Azure. Master the shift towards CI/CD, testing, and delivery, while preparing for the Designing and Implementing Microsoft DevOps Solutions exam!
Managing large files in a standard repository can slow down development because every clone downloads the full history of those assets. Git Large File Storage (Git LFS) addresses this issue by replacing large files in the repository with tiny text pointers while storing the actual data on a remote server. When a developer clones the repository, Git LFS only downloads these pointers and lazily fetches the full files when they are actually needed. This keeps local repositories small and ensures that common Git operations remain fast.
A system architecture diagram showing how Git LFS stores small text pointers in Azure Repos while large binary file contents are stored on a remote LFS server, fetched lazily by the developer's local machine.
Another option for handling large assets is git-fat, which also removes bulky binary history from the main repository. Unlike Git LFS, which uses its own dedicated infrastructure, git-fat connects directly to Azure Blob Storage to hold the actual files. This integration makes git-fat highly attractive for teams already utilizing Azure because they can reuse existing storage accounts and authentication workflows. The local repository still tracks text pointers, while the heavy lifting of storage is managed by Azure's cloud infrastructure.
To implement either solution in Azure Repos, developers must configure specific tracking patterns for binary extensions like video, image, or zip files. The team must also set up secure communication to allow the chosen tool to write to and read from the remote storage. Git LFS typically authenticates using OAuth tokens or SSH keys, whereas git-fat relies directly on Azure storage credentials. It is vital to keep these systems synchronized so that the pointers in the repository always match the files stored in the cloud.
After deploying one of these tools, teams should measure their impact to confirm they are working as expected. Developers should see a significant decrease in clone and fetch times once the repository history is cleared of heavy assets. Additionally, tracking storage costs in Azure Blob Storage helps confirm that cloud resources are being used efficiently. This strategy is most effective when developers have reliable network connections to the cloud storage backend.
As codebases grow into large monolithic repositories, daily Git operations can become slow and impact developer productivity. Git Scalar is a command-line tool designed to solve this by optimizing repository performance and limiting the amount of data downloaded to local machines. It achieves this primarily through sparse checkout and partial clone features. Sparse checkout allows developers to only download specific directories, while partial clone fetches file contents only for active files instead of downloading the entire commit history.
When teams need to share code across independent repositories, they can choose from several integration strategies. One method is using Git submodules, which configure a repository to point to a specific commit of another repository at a set path. This creates a strict parent-child link, though developers must manually update the pointers when changes occur. Alternatively, a subtree merge imports the external source code directly into a subdirectory of the main repository, simplifying local workflows but requiring different processes for pushing and pulling updates.
For a more decoupled architecture, teams can publish reusable libraries as versioned packages to Azure Artifacts. This service manages secure package feeds, allowing developers to share code without maintaining direct repository connections. Using packages establishes clear ownership boundaries and separates the release lifecycles of different components. Teams must choose this package-based approach when they want distinct versioning, whereas submodules or subtree merges are better for direct source-code collaboration.
Securing source code and meeting compliance guidelines in Azure Repos requires configuring Role-Based Access Control (RBAC). Administrators can assign built-in or custom roles to users and groups at the repository, branch, or folder path level. The Contributor role allows users to make modifications and push code, while the Reader role only permits viewing. Users with the Administrator role maintain full control over the repository settings and can configure access permissions.
To keep the main codebase stable, teams must configure branch protection policies that prevent developers from pushing code directly to protected branches. These policies enforce that all changes must go through a pull request and receive approval from a specified number of reviewers. Additionally, teams can require build validation steps, such as running automated tests, to ensure that incoming code does not break the build. This structure guarantees that code is thoroughly reviewed and tested before it is integrated.
Verifying that permissions are configured correctly requires regular monitoring and auditing. The security evaluation tool allows administrators to check the effective permissions of any user or group to ensure they do not have excessive access. Furthermore, security teams can analyze audit logs to track who made permission changes and when they occurred. This constant auditing helps detect unauthorized modifications early and maintains compliance with company security standards.
A standardized tagging strategy is necessary for organizing and tracking code changes across Azure Repos. Standardized naming conventions define how tags, which function as key-value pairs, are named and applied to commits. These rules ensure that all team members can easily understand what each tag represents, which enhances traceability across development stages. Without clear rules, tags can quickly become inconsistent, losing their effectiveness as organizational tools.
Developers can apply tags to specific commits or branches to mark important milestones in the application lifecycle, such as production releases. These tags can be created and managed using the Azure DevOps portal or through command-line tools like the Azure CLI. Consistently applying tags makes the repository history easier to navigate and supports release management processes by clearly defining which code is deployed. This practice establishes a permanent record of what code was active at any given release point.
Once tags are established, teams can execute tag-based queries to quickly search and filter repository contents. This allows developers to instantly locate all commits or artifacts associated with a specific tag, which is highly useful for security audits or release tracking. To maintain this system, teams should automate tagging within their deployment pipelines to eliminate manual errors. They should also perform regular audits to remove obsolete tags and keep the repository clean.
When developers need to recover lost work or understand past modifications in Azure Repos, they rely on specific Git commands. The git reflog command tracks every single update made to branch pointers, making it possible to find commits that are no longer linked to any branch. Meanwhile, the git log command displays a linear history of commits, allowing developers to see the chronological order of changes. Using these two commands together helps developers find the exact commit they need to recover.
After locating the correct commit, developers can choose between several commands to restore their work. The git checkout command switches the active branch or restores specific files to a previous state without altering current history. To undo changes safely on shared branches, the git revert command creates a new commit that rolls back specific changes while preserving the existing history. In contrast, the git reset command moves the branch pointer backward, which is useful for removing unwanted commits or unstaging files locally.
When developers must switch tasks without committing unfinished work, they can use the git stash command to temporarily save changes to a hidden area. Later, they can run git stash apply or git stash pop to bring those changes back and resume working. Additionally, the git cherry-pick command allows developers to copy a single commit from one branch and apply it directly onto another. This is particularly useful for pulling emergency bug fixes into a release branch without merging unrelated code.
Removing sensitive data, such as credentials, secrets, or large files, is essential for keeping cloud repositories secure. Simply deleting these files in a new commit does not secure the project because the sensitive data remains accessible in the repository history. To fully protect the project, developers must rewrite the entire Git history to permanently delete all traces of the compromised data. This ensures that the secret or large file is completely erased from all historical commits stored in Azure Repos.
Developers can use specialized tools to modify past commits and purge sensitive information safely. The git filter-repo tool is the modern standard because it performs these history rewrites quickly and securely. While the older, built-in git filter-branch tool is still available for custom tasks, it is slower and much more complex to use. Alternatively, the BFG Repo-Cleaner is a fast third-party tool specifically designed to target and strip out large files or passwords.
After rewriting history locally, the developer must synchronize these changes with Azure Repos by executing a force-push. Because a force-push overwrites existing history, it can disrupt other team members working on the same codebase. Therefore, it is critical to notify and coordinate with the team before performing this action. Once the push is complete, the team must verify that the remote repository has updated successfully and no longer contains the sensitive data.
Prepare and test your skills

Prepare and test your skills

Git Large File Storage (Git LFS) stores file data on its own dedicated remote server, while git-fat connects directly to Azure Blob Storage to hold the actual files. This makes git-fat attractive for teams already using Azure because they can reuse existing storage accounts and authentication workflows. Both tools replace large files in the repository with text pointers to keep local clones small.
Teams should use Azure Artifacts packages when they want clear ownership boundaries, distinct versioning, and a decoupled architecture without maintaining direct repository connections. Git submodules or subtree merges are better for direct source-code collaboration, as they create a link to another repository or import its source code directly.
Developers can use the git reflog command to track every update made to branch pointers and find commits that are no longer linked to any branch. After locating the correct commit, they can restore their work using commands like git checkout, git revert, or git reset to switch branches, undo changes, or move the branch pointer.
Rewriting Git history is essential to permanently delete all traces of sensitive data, such as credentials or secrets, from all historical commits. Simply deleting the files in a new commit does not secure the project because the data remains accessible in the repository history. Tools like git filter-repo or BFG Repo-Cleaner are used to perform this secure history rewrite.