# How to Use Git to Track Experimental and Control Group Data

By the end of this guide you will have a working Git repository that records every change to the group assignments, sample metadata, analysis code, and result tables of a study comparing an [experimental group](/blog/guides/experimental-group) with [a control group](/blog/guides/understanding-control-groups-in-clinical-trials-types-and-selection). You will be able to answer, from command output rather than memory, which sample belonged to which group on any date, when a label was corrected and why, and exactly which code version produced a given number.

You need Git installed (version 2.20 or newer covers every command shown here), a terminal, a text editor, and about 30 minutes. A free GitHub account is optional but recommended for backup and collaboration. The running example is a small two-group diet trial with bacterial community profiling of fecal samples. The same workflow fits cell culture, single-cell RNA-seq, proteomics, clinical trials, and behavioral experiments.

Tracking experimental and control group data in Git means tracking four things as one connected history: the group assignments, the metadata behind them, the code that analyzes them, and the results the code produces.

## Why Version Control Matters for Group-Comparison Studies

### What the data actually looks like

An experimental group receives the condition under test, and a control group is handled identically except for that condition. Everything that distinguishes the groups, and everything that could confound the comparison, is data.

In a single-cell study, the groups are cells from control and treatment donors, and the analysis may compare entire causal networks between them using computationally intensive Bayesian methods [1]. In a dairy nutrition trial, 18 lactating cows were homogeneously allocated to a control or an experimental diet, balanced on body condition score, days from calving, and daily milk production, before their fecal bacterial communities were profiled by 16S rRNA sequencing, which identifies bacteria in a community by reading the 16S [ribosomal RNA](/knowledge/bioinformatics/ribosomal-rna-structure-taxonomic-profiling) gene [2]. The allocation criteria and the resulting assignments are as much a part of the result as the sequencing reads.

### The provenance problem

Group comparisons fail quietly when the records behind the groups drift. A national commentary on perinatal quality collaboratives argues that inconsistent outcome measurement, caused partly by staggered adoption of revised birth certificates, can make genuine health improvements indistinguishable from data artifacts, and recommends systematic tracking and harmonization of the underlying data [3]. Version control is the cheapest form of systematic tracking a research group can adopt.

Git stores snapshots of your files, called commits, in a hidden folder named .git at the top of your project. Every commit records what changed, who changed it, when, and why. The whole history is called a repository. Git's own documentation frames commits as snapshots you can return to, and that property is precisely what group data needs.

## What Git Can and Cannot Track

### Plain text is first-class

Git compares files line by line, which makes it excellent for the text formats that carry group data: comma-separated values (CSV) sample sheets, tabular result files, R and Python scripts, shell pipelines, YAML configuration files (a plain-text configuration format), and Markdown notes. A commit that changes one group label produces a two-line diff you can read at a glance. A diff is the line-by-line record of what changed between two versions.

### Large binary files need a different plan

Raw sequencing output does not belong in ordinary Git history. A FASTQ file stores reads and quality scores as text, but laboratories keep it gzip-compressed, and Git sees the compressed file as an opaque binary blob. A BAM file, the compressed binary format for aligned reads, is opaque from the start. Committing gigabytes of these makes every clone and push slow, and hosted services will eventually refuse the push.

The standard plan has two parts. First, keep raw files on dedicated storage and commit a checksum manifest instead. A checksum is a fixed-length fingerprint computed from a file's contents. The SHA-256 algorithm produces 64 hexadecimal characters, and changing a single byte produces a completely different fingerprint. Second, for medium-sized files that must travel with the repository, use Git Large File Storage (LFS), a Git extension that keeps small pointer files in the history and stores the actual content on a separate server.

```
git lfs install
git lfs track "*.bam"
git add .gitattributes
```

The track command writes a rule into .gitattributes so that any file matching the pattern is routed through LFS. Hosted services apply storage and bandwidth quotas to LFS on free plans, so check the current limits before committing large files.

## A Repository Layout for a Two-Group Study

Keep one repository per study. A layout that works across amplicon, RNA-seq, and proteomics projects is:

- README.md, a short file telling a new student how to reproduce the analysis
- protocol/, the written design and a reference to the randomization list
- metadata/sample_sheet.csv, one row per sample with its group assignment
- metadata/data_dictionary.csv, the definition and allowed values for every column
- metadata/checksums.sha256, fingerprints of the raw files
- data/raw/, the reads themselves, ignored by Git or routed through LFS
- code/, analysis scripts, including the profiling and pathway-prediction steps used in studies such as the cow diet trial [2]
- results/, small tables and figures generated by the code

The rule of thumb is that Git should hold anything a reviewer might ask you to reproduce, and storage should hold anything Git cannot diff.

## Step-by-Step: Git for Experimental and Control Group Data

### Step 1. Install and configure Git

Install Git from your operating system's package manager or the official project website, then confirm it runs:

```
git --version
```

Expected output:

```
git version 2.45.1
```

Set the identity written into every commit, and set the default branch name:

```
git config --global user.name "Zubair Khalid"
git config --global user.email "zk@university.edu"
git config --global init.defaultBranch main
```

The, global flag writes these settings to your user-level configuration so they apply to every repository on the machine. Verify:

```
git config --global --list
```

```
user.name=Zubair Khalid
user.email=zk@university.edu
init.defaultBranch=main
```

### Step 2. Initialize the repository

Create a project folder and turn it into a repository:

```
mkdir diet-trial-16s && cd diet-trial-16s
git init
```

Expected output:

```
Initialized empty Git repository in /home/analyst/diet-trial-16s/.git/
```

Everything Git knows about the project lives inside .git. Deleting that folder deletes the history, so back it up like any other critical file.

### Step 3. Write the sample sheet and data dictionary

The sample sheet is the single source of truth for group membership. Use neutral sample identifiers and keep the group in its own column, never inside the identifier. The covariate columns below follow the balancing logic of the cow diet trial cited earlier [2].

```
sample_id,animal_id,group,batch,collection_date,days_in_milk,milk_kg_per_day,notes
S01,cow01,control,1,2026-03-02,120,28.4,
S02,cow02,control,1,2026-03-02,145,24.9,
S03,cow03,control,2,2026-03-09,132,26.0,
S10,cow10,experimental,1,2026-03-02,118,29.1,
S11,cow11,experimental,1,2026-03-02,150,23.7,
```

The full sheet in this example holds 18 rows, 9 per group.

Pair the sheet with a data dictionary that defines every column and its allowed values:

```
column,type,allowed_values,definition
sample_id,text,S01 to S18,Unique identifier for one sequencing sample
animal_id,text,cow01 to cow18,Animal the sample came from
group,factor,control or experimental,Diet arm assigned before sequencing
batch,factor,1 or 2,Sequencing run used for the library
collection_date,date,YYYY-MM-DD,Day the sample was collected
days_in_milk,integer,90 to 305,Allocation covariate
milk_kg_per_day,decimal,greater than 0,Allocation covariate
notes,text,free text,Corrections with the reason and date
```

Write these definitions before data collection. Systematic review protocols built on PRISMA-P, a reporting guideline for review protocols, specify the intervention group and the control group, including schedules, dosages, and durations, before any study is selected [4]. Your sample sheet deserves the same discipline.

Record intervention details in the dictionary too, because they are metadata you will otherwise lose. An antidiarrheal study in mice tested a crude 95 percent ethanol extract and a 90 percent ethanol eluted fraction of Alpinia oxyphylla and used LC-MS/MS, liquid chromatography paired with tandem mass spectrometry, to confirm chemical consistency [5]. A colitis study treated mice with palmitoylethanolamide at a human-equivalent dose of 123 mg/kg, given once or twice daily [6]. If the extract, fraction, dose, or schedule matters to the result, it belongs in a column, not in a paper notebook.

Commit the sheet and the dictionary:

```
git add metadata/sample_sheet.csv metadata/data_dictionary.csv
git commit -m "Add sample sheet with 18 samples and group definitions"
```

Expected output:

```
[main (root-commit) 3f2a91c] Add sample sheet with 18 samples and group definitions
 2 files changed, 26 insertions(+)
 create mode 100644 metadata/data_dictionary.csv
 create mode 100644 metadata/sample_sheet.csv
```

The -m flag supplies the commit message. Commit the sheet every time it changes, and dated history accumulates for free. Group sizes drift during a study. A 12-week randomized trial enrolled 174 adults and finished with 141 engaged participants, 67 in the intervention group and 74 in the control group [7]. Ten dated commits tell that story. One commit at the end erases it.

### Step 4. Record checksums for raw data

Generate a SHA-256 manifest for the raw reads:

```
sha256sum data/raw/*.fastq.gz > metadata/checksums.sha256
head -2 metadata/checksums.sha256
```

Expected output (each line is a 64-character digest, two spaces, then the path):

```
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  data/raw/S01_S1_L001_R1_001.fastq.gz
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad  data/raw/S01_S1_L001_R2_001.fastq.gz
```

For 18 samples sequenced in paired-end mode, the manifest lists 36 files, and verification should print 36 OK lines:

```
sha256sum -c metadata/checksums.sha256
```

```
data/raw/S01_S1_L001_R1_001.fastq.gz: OK
data/raw/S01_S1_L001_R2_001.fastq.gz: OK
```

The -c flag reads the manifest and recomputes each digest. Run it after every data transfer, disk copy, or collaborator handoff. A single FAILED line means the file changed in transit and must be re-copied. Commit the manifest:

```
git add metadata/checksums.sha256
git commit -m "Add SHA-256 manifest for 36 raw FASTQ files"
```

### Step 5. Ignore files that do not belong in history

Create a file named .gitignore so transient clutter never enters history:

```
data/raw/
data/tmp/
.Rhistory
.RData
__pycache__/
*.pyc
.DS_Store
```

A trailing slash matches a directory, and an asterisk is a wildcard. Commit it:

```
git add .gitignore
git commit -m "Ignore raw data, temp files, and OS clutter"
```

### Step 6. Audit changes with status, diff, and log

Three commands answer almost every provenance question. git status shows what is staged, unstaged, and untracked right now:

```
git status
```

```
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   metadata/sample_sheet.csv

no changes added to commit (use "git add" and/or "git commit -a")
```

git diff shows unstaged edits line by line. Suppose sample S15 was entered as control from the paper log, but the randomization list says experimental. Correct the cell, then look before you commit:

```
git diff metadata/sample_sheet.csv
```

```
diff --git a/metadata/sample_sheet.csv b/metadata/sample_sheet.csv
index 4b825dc..9c1d2e3 100644
--- a/metadata/sample_sheet.csv
+++ b/metadata/sample_sheet.csv
@@ -16,7 +16,7 @@
 S13,cow13,control,2,2026-03-09,128,27.2,
 S14,cow14,control,2,2026-03-09,139,25.5,
-S15,cow15,control,2,2026-03-09,141,24.8,entered from paper log
+S15,cow15,experimental,2,2026-03-09,141,24.8,corrected against randomization list
 S16,cow16,experimental,2,2026-03-09,126,28.0,
```

Lines beginning with a minus are the old version, and lines with a plus are the new version. Commit with a message that names the sample and the reason:

```
git add metadata/sample_sheet.csv
git commit -m "Fix S15 group to experimental per randomization list"
```

git log prints the history, and the, oneline flag compresses each commit to one line:

```
git log --oneline
```

```
7c4d2e1 Fix S15 group to experimental per randomization list
b8e3f02 Ignore raw data, temp files, and OS clutter
5d6c7a9 Add SHA-256 manifest for 36 raw FASTQ files
3f2a91c Add sample sheet with 18 samples and group definitions
```

Two deeper views are worth knowing. git log -p metadata/sample_sheet.csv prints every patch ever applied to the sheet, which is the complete story of your group assignments. git blame metadata/sample_sheet.csv annotates each line with the commit that last touched it. If a correction turns out to be wrong, git revert 7c4d2e1 creates a new commit that undoes the old one, which the Git documentation recommends over rewriting history that others already have.

Verify what Git is actually tracking at any moment:

```
git ls-files
```

```
.gitignore
metadata/checksums.sha256
metadata/data_dictionary.csv
metadata/sample_sheet.csv
```

### Step 7. Branch for exploratory analyses

A branch is a movable pointer to a line of work. Keep main as the stable record and do speculative work on a branch:

```
git switch -c analysis-pca
```

Expected output:

```
Switched to a new branch 'analysis-pca'
```

The -c flag creates the branch and switches to it in one step. Commits made here do not touch main. When the analysis proves useful, merge it back:

```
git switch main
git merge analysis-pca
```

```
Updating 7c4d2e1..9aa1b2c
Fast-forward
 code/pca_plot.R             | 42 ++++++++++
 results/pca_coordinates.csv | 19 ++++
 2 files changed, 61 insertions(+)
```

If the analysis is a dead end, delete the branch with git branch -D analysis-pca, and main never knew about it.

### Step 8. Commit analysis code and results together

Analyses that compare groups produce exactly the artifacts you should version as a set: the script, its parameters, and the result table. A retinal proteomics study compared 8 Alzheimer disease donors with 8 non-demented controls, separated cases from controls in [principal component analysis](/blog/data-analysis/principal-component-analysis-explained) (a method that projects samples onto axes of greatest variance), and reported 372 differentially abundant retinal proteins [8]. A result like that is reproducible only if the code that computed it sits in the same history as the table it produced.

Start with a guard script that fails loudly when the sheet drifts:

```r
# code/check_groups.R
ss <- read.csv("metadata/sample_sheet.csv")
stopifnot(nrow(ss) == 18)
stopifnot(!anyDuplicated(ss$sample_id))
stopifnot(all(ss$group %in% c("control", "experimental")))
print(table(ss$group))
```

```
Rscript code/check_groups.R
```

```
     control experimental 
           9            9 
```

stopifnot() halts with an error the moment an assumption breaks, for example Error: nrow(ss) == 18 is not TRUE. The DrugUtilisation R package applies the same idea at larger scale, pairing its analyses with comprehensive unit tests and standardized output formats so results stayed consistent across databases in the United Kingdom, Estonia, and the Netherlands [9]. You do not need to write a package to borrow the habit.

Then the analysis itself. Shannon diversity is an alpha diversity metric that summarizes how many species are present and how evenly their abundances are distributed:

```r
# code/alpha_diversity.R
ss   <- read.csv("metadata/sample_sheet.csv")
adiv <- read.csv("results/alpha_diversity.csv")
d <- merge(ss, adiv, by = "sample_id")
fit <- t.test(shannon ~ group, data = d)
print(fit)
writeLines(capture.output(sessionInfo()),
           "metadata/sessionInfo_alpha_diversity.txt")
```

```
Rscript code/alpha_diversity.R
```

```
        Welch Two Sample t-test

data:  shannon by group
t = -2.18, df = 15.7, p-value = 0.045
alternative hypothesis: true difference in means between group control and group experimental is not equal to 0
95 percent confidence interval:
 -0.71 -0.01
sample estimates:
mean in group control mean in group experimental 
                 3.42                       3.78 
```

The final line writes R's sessionInfo(), which lists package versions, next to the result. Commit code and environment together:

```
git add code/alpha_diversity.R metadata/sessionInfo_alpha_diversity.txt
git commit -m "Compare Shannon diversity between groups, record R session info"
```

Committing the script and its environment in one commit turns the history into a provenance chain rather than a pile of files.

### Step 9. Tag a data freeze

A tag is a named pointer to one commit that never moves. Use tags for the moments that matter, such as closing enrollment or locking the sheet before analysis:

```
git tag -a v1.0 -m "Data freeze: 18 samples sequenced, sample sheet locked"
git tag
```

```
v1.0
```

The -a flag creates an annotated tag, which stores a message, a date, and the tagger, unlike a lightweight tag, which is only a pointer. Inspect what the tag freezes:

```
git show v1.0 --stat
```

This prints the tag message followed by the files changed in that commit. Tag again at every manuscript submission, so reviewers who ask which data version a figure used get a one-word answer.

### Step 10. Push to GitHub and collaborate

A remote is a copy of the repository on another server. GitHub for researchers adds hosted backups, issue tracking, pull requests, and access controls on top of plain Git. Create an empty private repository on github.com, then connect and push:

```
git remote add origin git@github.com:yourlab/diet-trial-16s.git
git push -u origin main
git push origin v1.0
```

Expected output:

```
Enumerating objects: 16, done.
Counting objects: 100% (16/16), done.
Writing objects: 100% (12/12), 4.21 KiB | 4.21 MiB/s, done.
To github.com:yourlab/diet-trial-16s.git
 * [new branch]      main -> main
 * [new tag]         v1.0 -> v1.0
branch 'main' set up to track 'origin/main'
```

The -u flag links your local main to origin/main, so later pushes need only git push. Three hosted features earn their keep in laboratory settings. Issues turn to-do items like "re-run batch 2 checksums" into trackable threads. A pull request is a proposed set of commits that a collaborator reviews as a diff before merging, which is how a second pair of eyes gets onto every sample sheet edit. Branch protection rules, configured in the repository settings, can block direct pushes to main and require a reviewed pull request, which GitHub's documentation describes as the standard way to enforce review on shared branches.

Keep the repository private while data are unpublished, and keep human participant data out of hosted repositories. A quasi-experimental study that assigned 60 medical students to experimental and control groups collected writing samples and interview reflections [10]. De-identified metadata can live in Git. Identifiable content belongs in approved institutional storage, with the repository holding only analysis code and summaries.

## Reproducing a Result Months Later

Everything above pays off when a co-author asks, a year later, which code produced a figure. A clone is a full local copy of a remote repository with its entire history. Clone the repository, move to the tagged version, and rerun:

```
git clone git@github.com:yourlab/diet-trial-16s.git
cd diet-trial-16s
git checkout v1.0
Rscript code/alpha_diversity.R
```

Expected output:

```
Note: switching to 'v1.0'.
You are in 'detached HEAD' state. ...
HEAD is now at e9f01ab Compare Shannon diversity between groups, record R session info
```

Detached HEAD means you are viewing a tagged snapshot rather than a branch, which is exactly what you want for verification. To confirm which version you are on:

```
git describe --tags
```

```
v1.0
```

If commits have accumulated since the tag, the output extends to a string like v1.0-2-g1a2b3c4, meaning two commits after v1.0 at commit 1a2b3c4. Record that string in your notebook or manuscript, and anyone can return to the same state. To work from the tagged point, run git switch -c revisit-v1.

## Key Git Commands at a Glance

| Command | What it does | When to use it |
|--|--|--|
| git init | Creates a repository in the current folder | Once, at the start of a study |
| git status | Shows staged, unstaged, and untracked files | Before every commit |
| git add \<file\> | Stages a file for the next commit | After every deliberate edit |
| git commit -m "message" | Saves a snapshot with a message | One logical change per commit |
| git log, oneline | Prints one line per commit | Auditing when something changed |
| git log -p \<file\> | Prints the full patch history of one file | Tracing group label changes |
| git diff | Shows unstaged changes line by line | Reviewing an edit before staging |
| git switch -c \<name\> | Creates and enters a new branch | Starting an exploratory analysis |
| git merge \<name\> | Merges a branch into the current branch | Promoting a validated analysis |
| git tag -a v1.0 -m "note" | Creates an annotated tag | Freezing the sheet or a manuscript version |
| git remote add origin \<url\> | Connects a hosted remote | Linking the study to GitHub |
| git push -u origin main | Uploads commits and sets tracking | First push, then plain git push |
| git pull | Downloads and merges remote commits | Before starting work each day |
| git revert \<hash\> | Adds a commit that undoes an old one | Undoing an error on shared history |
| git restore \<file\> | Discards uncommitted changes to a file | Undoing an accidental edit |
| sha256sum -c manifest | Verifies files against checksums | Before and after any data transfer |

## When Commands Fail: Four Common Errors

![Decision path for a rejected push: pull the collaborator commits, resolve the sample sheet conflict, then push again.](/article-images/illustrations/git-experimental-control-group-data-push-rejected-triage.webp)

**1. Git runs outside a repository.**

```
fatal: not a git repository (or any of the parent directories): .git
```

You are in the wrong folder. Change into the project directory, or run git init if the folder is meant to be a new repository.

**2. A push is rejected because the remote moved ahead.**

```
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:yourlab/diet-trial-16s.git'
```

A collaborator pushed commits you do not have. Run git pull to merge their work, resolve any conflict in the sample sheet by keeping the correct value, then push again.

**3. A checkout is blocked by uncommitted edits.**

```
error: Your local changes to the following files would be overwritten by checkout:
        metadata/sample_sheet.csv
Please commit your changes or stash them before you switch branches.
Aborting
```

Commit the edit if you want to keep it. If you do not, git restore metadata/sample_sheet.csv discards it, or git stash parks it and git stash pop brings it back later.

**4. An HTTPS push fails authentication.**

```
fatal: Authentication failed for 'https://github.com/yourlab/diet-trial-16s.git/'
```

GitHub no longer accepts account passwords for Git over HTTPS. Create a personal access token in your GitHub settings and use it in place of the password, or set up an SSH key as used in the remote URL in Step 10.

## Tips for Keeping the History Useful

- **One logical change per commit.** A commit that fixes one label is reviewable. A commit that fixes six labels, renames columns, and edits a script hides mistakes.
- **Write messages that say what and why.** "Fix S15 group to experimental per randomization list" beats "update".
- **Commit metadata on collection days.** The sheet should change in step with the bench work.
- **Tag every freeze.** Enrollment close, analysis lock, and each submission get a tag.
- **Capture the software environment with the results.** sessionInfo() in R, pip freeze or conda env export in Python, and module lists on shared clusters.
- **Write the README for the next person.** Assume a new student knows nothing and give them the five commands that reproduce the main result.

This is git for scientists in one habit. The repository, not anyone's memory, holds the story of the groups. A sensible next step is to turn this layout into a laboratory template repository so every new study starts from the same skeleton.

## Common Mistakes and Limitations

1. **Committing raw reads or BAM files.** History balloons, clones take hours, and pushes fail. Keep raw data on dedicated storage, commit checksums, and reserve LFS for the few files that must travel with the repository.
2. **Keeping group labels only in a spreadsheet on one laptop.** If the file is not committed, it has no history, no author, and no date. Move the sheet to CSV in Git and treat the spreadsheet as an export.
3. **Saving one giant commit at the end of the study.** The audit trail is the value. Commit each enrollment update, each label correction, and each analysis rerun as it happens.
4. **Vague messages.** "Update" and "fix" tell a reader nothing a year later. Name the sample and the reason.
5. **Force pushing shared branches.** git push, force rewrites history that collaborators have already cloned and can silently erase a correction. Use git revert instead.
6. **Binary office documents as the canonical record.** Word and Excel files produce diffs that read "binary files differ". Plain text formats make every change visible.
7. **No environment capture.** A perfect Git history cannot reproduce an analysis if package versions are unknown. Write sessionInfo() output or a conda environment export next to every result.
8. **Human participant data on public remotes.** Once pushed publicly, data cannot be reliably unpulled. Keep unpublished work in private repositories and identifiable content out of Git entirely.
9. **Assuming a clean history validates the science.** Git records what you typed. It does not know whether a label matches the animal. Check assignments against the randomization list with a second person before tagging a freeze.
10. **Treating Git as archival backup.** Git documents provenance for text. It is not a substitute for institutional storage, a [data management](/blog/guides/data-management-basics-principles-processes-and-best-practices) plan, or a [laboratory information management system](/knowledge/bioinformatics/lims-explained-lab-information-management-systems).

One limitation deserves its own note. If the analyst must remain blinded, meaning unaware of group membership until the analysis is locked, keep the key that maps codes to groups in a separate restricted repository and hand analysts files with coded group labels. The analysis repository then documents everything except the one thing the analyst must not see.

## Frequently Asked Questions

### Should raw sequencing files go into Git?

No. Keep raw reads on dedicated storage and commit a SHA-256 manifest so you can prove they are unchanged. Reserve Git LFS for the medium-sized files that genuinely need to travel with the repository.

### Can Git track Excel files?

Technically yes, but the history will be useless. Git compares text line by line, and a workbook is a compressed binary blob, so diffs show only that binary files differ. Keep group data in CSV and export to Excel only when someone insists.

### How do I fix a wrong group label that was already committed?

![Flowchart for fixing a wrong group label: edit the cell, diff it, commit with a reason, then revert if it was already pushed.](/article-images/illustrations/git-experimental-control-group-data-label-fix-path.webp)

Correct the value, commit, and name the sample and the reason in the message. If the wrong version was already pushed, use git revert, which adds a new commit that undoes the old one without rewriting shared history.

### What is the difference between Git and GitHub?

Git is the version control program running on your machine. GitHub is a hosting service that stores repositories online and adds issues, pull requests, and access controls.

### How large is too large for a repository?

Too large when binary files make clones slow or pushes fail. Text histories grow slowly. Raw reads, BAM files, and microscopy images belong on storage or in LFS, not in ordinary Git history.

### How do I share data with a collaborator without pushing the raw files?

Commit the checksum manifest and the sample sheet, transfer the raw files through your institution's approved service, and have the collaborator run sha256sum -c to confirm the copies match.

### Does this workflow work for R, Python, and workflow engines?

Yes. Git is language-agnostic. Commit scripts, parameter files, and an environment capture such as sessionInfo() output or a conda environment export alongside each result.

### How can I prove the control and experimental groups were not mixed up?

Read the history of the sample sheet. git log -p shows every label change with its date and message, tags mark the locked assignments, and checksums show the raw files behind them never changed.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Should raw sequencing files go into Git?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. Keep raw reads on dedicated storage and commit a SHA-256 manifest so you can prove they are unchanged. Reserve Git LFS for the medium-sized files that genuinely need to travel with the repository."
      }
    },
    {
      "@type": "Question",
      "name": "Can Git track Excel files?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Technically yes, but the history will be useless. Git compares text line by line, and a workbook is a compressed binary blob, so diffs show only that binary files differ. Keep group data in CSV and export to Excel only when someone insists."
      }
    },
    {
      "@type": "Question",
      "name": "How do I fix a wrong group label that was already committed?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Correct the value, commit, and name the sample and the reason in the message. If the wrong version was already pushed, use git revert, which adds a new commit that undoes the old one without rewriting shared history."
      }
    },
    {
      "@type": "Question",
      "name": "What is the difference between Git and GitHub?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Git is the version control program running on your machine. GitHub is a hosting service that stores repositories online and adds issues, pull requests, and access controls."
      }
    },
    {
      "@type": "Question",
      "name": "How large is too large for a repository?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Too large when binary files make clones slow or pushes fail. Text histories grow slowly. Raw reads, BAM files, and microscopy images belong on storage or in LFS, not in ordinary Git history."
      }
    },
    {
      "@type": "Question",
      "name": "How do I share data with a collaborator without pushing the raw files?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Commit the checksum manifest and the sample sheet, transfer the raw files through your institution's approved service, and have the collaborator run sha256sum -c to confirm the copies match."
      }
    },
    {
      "@type": "Question",
      "name": "Does this workflow work for R, Python, and workflow engines?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. Git is language-agnostic. Commit scripts, parameter files, and an environment capture such as sessionInfo() output or a conda environment export alongside each result."
      }
    },
    {
      "@type": "Question",
      "name": "How can I prove the control and experimental groups were not mixed up?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Read the history of the sample sheet. git log -p shows every label change with its date and message, tags mark the locked assignments, and checksums show the raw files behind them never changed."
      }
    }
  ]
}
</script>

## Sources

1. [BAYESIAN DIFFERENTIAL CAUSAL DIRECTED ACYCLIC GRAPHS FOR OBSERVATIONAL ZERO-INFLATED COUNTS WITH AN APPLICATION TO TWO-SAMPLE SINGLE-CELL DATA.](https://pubmed.ncbi.nlm.nih.gov/40893137/)
2. [Influence of olive cake dietary supplementation on fecal microbiota of dairy cows.](https://pubmed.ncbi.nlm.nih.gov/37206333/)
3. [Scaling evidence: national causal evaluation of perinatal quality collaboratives needs better data.](https://pubmed.ncbi.nlm.nih.gov/42253882/)
4. [What are the digestion and absorption models used to reproduce gastrointestinal protein processes?: A protocol for systematic review.](https://pubmed.ncbi.nlm.nih.gov/34397697/)
5. [Antidiarrheal effect of Alpinia oxyphylla Miq. (Zingiberaceae) in experimental mice and its possible mechanism of action.](https://pubmed.ncbi.nlm.nih.gov/25861952/)
6. [Amelioration of Dextran Sodium Sulfate-Induced Colitis in Mice through Oral Administration of Palmitoylethanolamide.](https://pubmed.ncbi.nlm.nih.gov/38790962/)
7. [Personalized Mobile App-Based Messaging and Step Tracking for Improving Walking Behavior in Adults: Randomized Controlled Trial.](https://pubmed.ncbi.nlm.nih.gov/42753258/)
8. [Retinal proteome changes mirror brain pathology and reveal synaptic and cytoskeletal dysfunction in Alzheimer's disease.](https://pubmed.ncbi.nlm.nih.gov/42525245/)
9. [DrugUtilisation: An R Package to Support Drug Utilisation Research Using the OMOP Common Data Model.](https://pubmed.ncbi.nlm.nih.gov/42448616/)
10. [Evaluating a corpus-based intervention in medical English writing: a mixed-methods study.](https://pubmed.ncbi.nlm.nih.gov/42310596/)