Source Control and Configuration ManagementIntroductionModern software and cloud services are built by teams whose work changes continuously. Source code, infrastructure definitions, deployment scripts, documentation, security policies, and application settings may all need to be modified, tested, reviewed, and released. Without disciplined control, teams can overwrite one another’s work, lose earlier versions, deploy inconsistent environments, or be unable to determine who introduced a defect. Source control and configuration management provide the foundations for reliable DevOps. Source control records changes to files over time and supports collaboration. Configuration management identifies the components that make up a system, controls their versions and relationships, and ensures that environments can be reproduced. Together, these practices make change visible, reviewable, reversible, and increasingly automatable. Git is the dominant distributed version-control system used in contemporary software delivery. Platforms such as GitHub, GitLab, and Bitbucket add collaboration features including remote repositories, pull requests, code review, access control, issue tracking, and automated CI/CD integration. The underlying concepts, however, remain applicable across platforms. Learning ObjectivesBy the end of this chapter, you should be able to: - explain repositories, working trees, staging areas, commits, branches, and remotes;
- create and use Git commits with meaningful history;
- compare merging and rebasing and resolve basic conflicts;
- describe pull requests, code reviews, tags, and release workflows;
- apply access-control and branch-protection practices;
- distinguish source control from broader configuration management;
- manage configuration safely using versioning, templates, secrets protection, and environment consistency; and
- evaluate practical risks and trade-offs in a DevOps workflow.
1. The Purpose of Source ControlSource control, also called version control, is a system for recording and managing successive versions of digital artefacts. An artefact may be a source file, test, database migration, infrastructure-as-code file, container definition, pipeline configuration, or technical document. A source-control system provides several capabilities: - History: It records what changed, when, and by whom.
- Collaboration: Multiple people can work on related files without relying on manually exchanged copies.
- Experimentation: Developers can isolate work in branches and return to a stable version when necessary.
- Review: Proposed changes can be examined before they become part of an approved code line.
- Recovery: Earlier versions can be restored or investigated.
- Automation: A commit or merge can trigger tests, security scans, packaging, and deployment.
Version control is not a substitute for testing, documentation, or communication. A repository can preserve a badly designed change perfectly. Its value depends on sound practices around commits, reviews, permissions, and automated validation. Centralized and Distributed ModelsIn a centralized version-control system, a primary server stores the repository history and users generally obtain files from that server. In a distributed version-control system, each clone contains a complete or near-complete history. Git is distributed: a developer can create commits locally, inspect history, and compare versions without continuous access to a server. A remote repository is then used to exchange changes and provide shared collaboration services. The distributed model improves local productivity and resilience, but it also creates governance responsibilities. A developer may create many local histories that are never shared, and sensitive data may remain in cloned repositories. Access controls and secure handling therefore remain important even when work is performed locally. 2. Git’s Core Objects and Working ModelA Git project normally contains a working tree, a staging area, and a repository database. - The working tree is the checked-out set of files currently being edited.
- The staging area, also called the index, records the exact changes selected for the next commit.
- The local repository stores commits and related objects in the
.git directory. - A remote repository is another repository, usually hosted on a shared platform, with which local work is exchanged.
The staging area is an important distinction. A developer can edit three files but stage only one of them for a commit. This permits a commit to represent one coherent logical change rather than every modification currently present in the working tree. A commit is a snapshot reference accompanied by metadata such as its author, committer, message, and parent commit. Git commonly identifies commits with a cryptographic hash. The hash is not a human-readable description, but it helps identify content and detect unintended alteration. A commit is best understood as an immutable historical record; correcting an unpublished local commit is different from rewriting history that others already use. A Basic Local WorkflowA typical sequence is: git clone <repository-url>
cd <project-directory>
git switch -c feature/meaningful-name
# edit files
git status
git diff
git add <files>
git diff --staged
git commit -m "Add input validation"
git push -u origin feature/meaningful-name git status reports the state of the working tree and staging area. git diff displays unstaged differences, while git diff --staged displays what the next commit will contain. These inspection commands are essential safeguards against committing incomplete, unrelated, or sensitive files.
A commit message should explain the purpose of the change. Messages such as “Update files” provide little value. A message such as “Reject expired access tokens” gives future readers a useful summary. A project may adopt a convention, for example a short imperative subject followed by an optional explanatory body. Ignore RulesThe .gitignore file specifies files that Git should normally ignore, such as compiled output, local editor settings, temporary files, and dependency caches. Ignore rules reduce noise, but they do not remove a file that has already been tracked. A secret accidentally committed to history must be treated as exposed: it should be revoked or rotated, removed appropriately, and investigated. Merely deleting it in a later commit is not sufficient because earlier commits may remain available. 3. Repositories, Remotes, and BranchesA repository is the versioned project database and its associated working files. A repository may be public, private, internal, or hosted within an organization. A remote is a named reference to another repository. The name origin is a conventional default, not a special technical requirement. A branch is a movable reference to a line of development. In Git, a branch is lightweight: it points to a commit, and new commits advance that pointer. Branches do not automatically represent complete independent copies of all files. They provide labels that help people develop and integrate changes. Common branch categories include: | Branch type | Typical purpose |
|---|
| Main or trunk | The integrated, potentially releasable product line | | Feature branch | A focused change under development | | Release branch | Stabilization of a planned release, where used | | Hotfix branch | A narrowly scoped urgent correction |
Branch naming should be predictable and descriptive, such as feature/payment-timeout or fix/session-expiry. Teams should avoid long-lived branches where possible because divergence increases integration difficulty. Trunk-based development uses short-lived branches and frequent integration; other teams use a more structured release-branch model. Neither is universally correct. The appropriate model depends on product risk, release cadence, regulatory controls, and team capability. Useful commands include: git branch
git switch main
git switch -c feature/report-export
git fetch origin
git log --oneline --graph --decorate
git pull --ff-only origin main
git push origin feature/report-export git fetch retrieves remote information without changing the current working branch. git pull normally combines fetching with integration, but teams should understand whether it merges or rebases and should avoid unintentionally integrating unreviewed changes. Explicit commands make the operation easier to reason about.
4. Integration: Merge, Rebase, and Conflict ResolutionWhen two branches have diverged, their changes must be integrated. A merge creates a new commit that combines the histories, unless a fast-forward is possible. A fast-forward simply moves a branch reference forward because no divergent commit exists. A rebase replays commits from one base onto another. It can produce a linear-looking history, but the replayed commits receive new identities. Consequently, rebasing commits already shared with others can disrupt collaborators. A practical rule is: rebase private or explicitly disposable work; merge or use an agreed safe strategy for public history. Neither merge nor rebase automatically proves that the resulting software is correct. After integration, run relevant tests, inspect the resulting diff, and verify configuration and dependencies. A conflict occurs when Git cannot determine how competing changes should be combined, often because two branches modify overlapping lines. A responsible conflict-resolution process is: - read the conflict markers and understand both changes;
- consult the intended behavior, tests, and the other contributor when necessary;
- edit the file into the desired final form;
- remove conflict markers;
- stage the resolved file;
- continue the merge or rebase; and
- run tests and inspect the final result.
The correct resolution is not always “keep ours” or “keep theirs.” A conflict may reveal a deeper design disagreement, a changed interface, or a missing test. If the intended behavior is unclear, aborting the operation and clarifying requirements is safer than guessing. 5. Pull Requests and Code ReviewA pull request (PR), also called a merge request on some platforms, is a controlled proposal to integrate changes into a target branch. It normally contains a description, commits, automated checks, reviewer discussion, and a decision to merge, request changes, or close the proposal. An effective pull request should: - have a focused scope;
- state the problem and the proposed solution;
- identify tests performed and results;
- describe configuration, migration, security, or operational effects;
- link relevant work items; and
- remain small enough for reviewers to understand.
Code review is a quality and knowledge-sharing activity, not merely an approval ritual. Reviewers should examine correctness, maintainability, security, tests, observability, performance implications, and compatibility. They should distinguish blocking defects from suggestions and express criticism of the change rather than the person. Automated checks commonly include formatting, unit tests, integration tests, dependency checks, static analysis, secret detection, container scanning, and infrastructure validation. Automation supplies repeatability but does not replace human judgment. A test suite may omit an important scenario, and a security scanner may report a false positive or miss a design-level weakness. A branch-protection policy may require successful checks, reviews by appropriate code owners, signed commits, or a linear history before merging. Such controls should reflect risk. Excessive approval requirements can create bottlenecks, while weak controls can permit unauthorized or unsafe changes. 6. Tags, Releases, and TraceabilityA tag is a named reference to a particular commit. Tags are useful for identifying release points such as v2.3.0. An annotated tag includes metadata and is generally preferable for formal releases: git tag -a v2.3.0 -m "Release version 2.3.0"
git push origin v2.3.0 A release process should connect a version to its source commit, build outputs, test evidence, dependencies, and deployment record. This is called traceability. It supports rollback, incident investigation, auditing, and communication with users. Tags should not be moved casually after publication. If a release artifact changes while retaining the same version label, operators may unknowingly deploy different content. Immutable tags and immutable artifact storage provide stronger reproducibility. Some organizations use a versioning policy such as semantic versioning, in which a major version indicates incompatible public changes, a minor version indicates backward-compatible functionality, and a patch version indicates backward-compatible fixes. The policy is useful only when the team applies it consistently and defines what “compatibility” means for its product. 7. Access Control and Repository GovernanceRepository access should follow least privilege: each person or service receives only the permissions needed for its role. Typical roles include read-only user, contributor, reviewer, maintainer, and administrator. Permissions should be granted to groups or teams where practical rather than managed through many individual exceptions. Important controls include: - multi-factor authentication for human accounts;
- protected main branches;
- required reviews and status checks;
- code-owner approval for sensitive directories;
- restricted creation, deletion, and movement of tags;
- short-lived, scoped tokens for automation;
- audit logs for access and changes;
- periodic review of membership and permissions; and
- removal of access when a person changes role or leaves.
Secrets require particular care. Passwords, private keys, API tokens, and certificates should not be stored in ordinary source files or committed to repositories. They should be supplied through an approved secret-management system, protected CI/CD variables, or a cloud identity mechanism. A configuration file containing a placeholder is not itself a secret, but careless examples can still encourage unsafe copying. Governance also includes licensing and intellectual-property considerations. A repository may contain third-party dependencies whose licenses impose attribution or distribution obligations. Organizations should define contribution rules, acceptable-use policies, retention requirements, and procedures for responding to vulnerabilities or accidental disclosure. 8. Configuration ManagementConfiguration management is the disciplined identification, control, documentation, and verification of the components and settings that define a system. It extends beyond source code. A cloud application may depend on application configuration, operating-system settings, container images, infrastructure definitions, database schemas, network rules, feature flags, certificates, external services, and deployment policies. A useful configuration-management process contains four connected activities: - Identification: Define configuration items, versions, owners, and relationships.
- Control: Review and authorize proposed changes.
- Status accounting: Record the current and historical state of items.
- Verification and audit: Confirm that the recorded state matches the intended and deployed state.
A configuration item is a component managed as a distinct unit. Examples include a container image digest, a Terraform module version, a Kubernetes manifest, or a database migration. A baseline is an approved, identifiable configuration used as a reference point. A change record explains what is changing, why, who approved it, and how it can be validated or reversed. Configuration as CodeConfiguration as code stores infrastructure and operational definitions in machine-readable, versioned files. Examples include Terraform files, Kubernetes manifests, Ansible playbooks, Dockerfiles, and CI pipeline definitions. The benefits include repeatability, peer review, auditability, and the ability to recreate environments. The risks include accidental destructive changes, insecure defaults, provider drift, and false confidence when code is not tested or applied consistently. Configuration should be parameterized where environments legitimately differ. For example, the same application definition may use different database endpoints in development and production. However, excessive variation creates “configuration drift” and makes behavior difficult to predict. Teams should keep environments as similar as practical and make differences explicit. A strong pattern separates: - code and templates, which may be versioned in a repository;
- environment-specific values, which are controlled and documented; and
- secrets, which are stored in a dedicated protected system.
Generated files should normally be reproducible from their source definitions rather than edited manually. If a manual emergency change is necessary, it should be recorded and reconciled into the managed configuration quickly. Desired State and DriftMany configuration tools use a desired-state model. The team declares the intended state, and a tool compares actual state with that declaration and attempts to converge the system. Drift occurs when actual state differs from the approved desired state, perhaps because of an emergency console change, an undocumented administrator action, or a tool failure. Drift detection is valuable, but automatic correction must be used carefully. A tool that immediately overwrites a legitimate emergency change can increase an outage. Safe operation requires change windows or policy, backups where appropriate, review of proposed actions, and clear ownership of reconciliation. 9. An Illustrative Case: A Cloud Billing ServiceBackground. A small organization operates a cloud billing service. Developers commit application code, database migrations, Dockerfiles, and Terraform infrastructure definitions to one Git repository. The production environment is deployed from the main branch. Problem. Engineers have been editing production settings manually through a cloud console. A developer accidentally commits a test API token. Another change passes unit tests but fails in production because the staging database uses a different schema. The team cannot reliably identify which configuration was active during an incident. Analysis. The organization has source control but weak configuration management. Production state is not fully represented by versioned definitions, credentials are not separated from ordinary configuration, and the release process lacks traceability. The issue is organizational as well as technical: the team has optimized for immediate speed rather than controlled change. Approach. The team takes the following steps: - revokes and replaces the exposed token and scans repository history;
- defines infrastructure, database migrations, and pipeline files as configuration items;
- stores non-secret environment values in reviewed configuration files and secrets in a managed secret store;
- protects
main and requires review plus automated checks; - creates a staging deployment that applies the same migration process used in production;
- adds drift detection for important cloud resources;
- creates an annotated release tag only after tests and approval; and
- records the release commit, image digest, migration version, and deployment result.
Outcome. The team can reproduce a release more reliably, identify the source of a deployed image, and investigate configuration differences. Deployment takes slightly longer because checks and approvals are explicit, but emergency recovery is faster because rollback information is available and undocumented console changes are reduced. Learning points. Versioning files alone is insufficient. Effective control requires secure secret handling, review, environment consistency, status visibility, and operational discipline. The team also learns that a failed automated check is useful feedback, not merely a barrier to delivery. 10. Challenges, Limitations, and Contemporary PracticeGit records history, but it does not automatically understand business intent. Poorly structured commits, huge pull requests, and meaningless messages reduce its value. Merge conflicts are a normal consequence of parallel work, not evidence that Git is defective. They can be reduced through modular design, communication, short-lived branches, and frequent integration. Large binary files can make repositories slow and difficult to clone. Teams may use an appropriate large-file extension or artifact repository instead of storing every build output in Git. Build artifacts should generally be produced by a pipeline and stored in an artifact registry, while the repository stores the definitions needed to reproduce them. Reproducibility remains difficult when dependencies are unpinned, external services change, timestamps vary, or build environments differ. Pinning versions, recording checksums where appropriate, using controlled build environments, and generating software bills of materials can improve confidence. A lock file may constrain dependency resolution, but it must itself be maintained and reviewed. Artificial-intelligence tools can assist with commit summaries, code suggestions, conflict explanations, and review prompts. They can also generate insecure code, expose confidential context, misunderstand repository conventions, or create misleading explanations. AI-generated changes require the same review, testing, licensing consideration, and security scrutiny as human-generated changes. An AI tool should not receive secrets or proprietary source unless organizational policy and technical safeguards permit it. A mature DevOps organization treats source control as a central evidence system. Commits, reviews, automated checks, release tags, deployment records, and configuration states form a chain of accountability. This chain supports technical reliability, but it must be balanced with privacy, access minimization, retention policies, and the right to remove or rotate sensitive data when exposed. Best-Practice WorkflowA practical certificate-level workflow can be summarized as follows: - Start from an up-to-date repository and create a focused branch.
- Make one coherent change at a time.
- Inspect status and differences before staging.
- Commit with a clear message and avoid secrets or generated clutter.
- Push the branch and open a focused pull request.
- Use automated tests, security checks, and configuration validation.
- Request appropriate review and resolve comments constructively.
- Integrate only after required checks pass.
- Tag approved releases and retain traceability to artifacts and deployments.
- Monitor for configuration drift and reconcile emergency changes.
These practices are simple, but their effectiveness depends on consistency. Teams should document their chosen branching, review, release, and configuration policies and improve them using evidence from incidents and delivery performance. Chapter SummarySource control records the evolution of software and related artefacts, while configuration management controls the complete set of components and settings that produce a working system. Git’s working tree, staging area, commits, branches, and remotes support local development and collaboration. Meaningful commits, focused branches, careful integration, and conflict resolution create a usable history. Pull requests and code reviews provide human governance around automated validation. Tags and release records connect deployed artefacts to source commits. Access controls, branch protection, multi-factor authentication, audit logs, and secret-management systems reduce unauthorized or unsafe change. Configuration management identifies configuration items, establishes baselines, records status, and verifies that deployed state matches approved intent. Configuration as code improves repeatability but does not eliminate drift, insecure defaults, or the need for review. Reliable DevOps therefore combines technical tools with disciplined processes, security awareness, and shared responsibility. Key TermsBranch: A movable reference to a line of development in a repository. Commit: A recorded version of selected changes with history and metadata. Configuration item: A component or setting managed under configuration control. Configuration drift: A difference between approved or desired configuration and actual deployed state. Configuration management: Identification, control, recording, and verification of system components and settings. Fast-forward: An integration in which a branch reference moves forward without divergent history. Git: A distributed version-control system. Merge: Integration of histories from two lines of development. Pull request: A controlled proposal to integrate changes into a target branch. Remote: A named reference to another repository used for exchanging changes. Repository: A versioned collection of project files and history. Review: Human examination of proposed changes for quality, security, and correctness. Secret: Sensitive authentication or encryption material such as a token or private key. Staging area: The set of changes selected for the next commit. Tag: A named reference to a specific commit, often used for releases. Trunk-based development: A practice emphasizing frequent integration into a central main line, usually with short-lived branches. Version control: The recording and management of successive versions of digital artefacts. Working tree: The files currently checked out and available for editing. Review QuestionsShort Answer Questions- What is the difference between the working tree, staging area, and repository in Git?
- Why should a team avoid committing secrets even if they are deleted in a later commit?
- What is the purpose of a pull request?
- Define configuration drift and give one possible cause.
- Why are release tags useful for operational traceability?
Long Answer Questions- Explain a complete Git workflow from creating a feature branch through pull-request integration. Include the role of inspection commands, commits, automated checks, and review.
- Compare merge and rebase. Explain how they affect history and identify circumstances in which each may be appropriate.
- Describe how access control, branch protection, multi-factor authentication, and audit logs contribute to repository governance.
- Explain configuration as code and discuss its benefits and limitations for cloud infrastructure.
- Describe the relationship between source control, configuration management, release management, and CI/CD reliability.
Analytical / Application Questions- Two developers modify the same configuration file, and Git reports a conflict. Design a safe resolution process and identify the checks that should occur before integration.
- A production database was changed manually during an outage, but the repository still describes the old schema. Analyze the risks and propose a reconciliation and governance process.
- A team wants every developer to have administrator access so that work is faster. Evaluate this proposal using least privilege, operational risk, and practical alternatives.
Multiple Choice Questions with AnswersQuestion 1Which Git area contains changes selected for the next commit? A. The remote repository B. The staging area C. The tag database D. The issue tracker Correct Answer: B. The staging area Question 2What is the primary purpose of a pull request? A. To propose and review changes before integrating them B. To permanently delete a branch C. To store production passwords D. To compile binary files locally Correct Answer: A. To propose and review changes before integrating them Question 3Which practice best protects a secret that was accidentally committed? A. Rename the file and keep the same secret B. Delete only the latest copy C. Revoke or rotate the secret and investigate its exposure D. Add the secret to a README file Correct Answer: C. Revoke or rotate the secret and investigate its exposure Question 4What does a Git tag commonly identify? A. A specific commit, often representing a release B. An untracked temporary file C. A reviewer’s permission level D. A merge conflict marker Correct Answer: A. A specific commit, often representing a release Question 5What is configuration drift? A. A faster method of cloning a repository B. A difference between intended and actual system configuration C. A type of Git commit message D. A technique for deleting old branches Correct Answer: B. A difference between intended and actual system configuration Question 6Which statement about rebasing shared public commits is most accurate? A. It never changes commit identities B. It can rewrite history and disrupt collaborators C. It automatically resolves all semantic conflicts D. It removes the need for testing Correct Answer: B. It can rewrite history and disrupt collaborators Question 7Which control most directly supports least privilege? A. Giving every user administrator access B. Using shared permanent passwords C. Granting only permissions required for a person’s role D. Disabling audit logs Correct Answer: C. Granting only permissions required for a person’s role Question 8Why is a focused pull request generally easier to review? A. It reduces the number of unrelated changes reviewers must understand B. It prevents all automated testing C. It guarantees that the code has no defects D. It eliminates the need for branch protection Correct Answer: A. It reduces the number of unrelated changes reviewers must understand Question 9Which item should normally be stored in a dedicated secret-management system rather than ordinary source files? A. A public function name B. A private API token C. A non-sensitive unit test D. A documented license notice Correct Answer: B. A private API token Question 10What is a key benefit of configuration as code? A. It makes review and repeatable environment creation possible B. It guarantees that infrastructure changes are harmless C. It eliminates all environment differences automatically D. It allows secrets to be committed safely Correct Answer: A. It makes review and repeatable environment creation possible
|