ఈ పేజీలో
git commit
సంక్షిప్తంగా: git commit మీ Staging Area (index) యొక్క స్నాప్షాట్ను తీసుకుని Git object databaseలో శాశ్వతంగా రాస్తుంది. తెర వెనుక, Git మీ డైరెక్టరీ నిర్మాణాన్ని ట్రీ ఆబ్జెక్టులుగా ప్యాకేజ్ చేసి, మెటాడేటాను (author, committer, parent commit hashes, message) జాబితా చేసే కమిట్ ఆబ్జెక్ట్ను రాస్తుంది. తర్వాత active branch refను కొత్త కమిట్ hash వైపు చూపేలా నవీకరిస్తుంది.
git commit వాస్తవానికి ఏం చేస్తుంది?
git commitను అర్థం చేసుకోవాలంటే, Git మార్పులను “diffs” లేదా “deltas”గా ట్రాక్ చేస్తుందనే సాధారణ అపోహను ముందుగా పక్కన పెట్టాలి. Gitలో ప్రతి కమిట్ మొత్తం ప్రాజెక్ట్కి పూర్తి స్నాప్షాట్.
మీరు commit చేసినప్పుడు, లైన్లలో చేసిన మార్పుల జాబితాను సేవ్ చేయడం కాదు. బదులుగా, staging areaకు ఫోటో తీసి, దానికి ప్రత్యేకమైన శాశ్వత identifier ఇస్తారు. ఒక కమిట్లో ఫైల్ మారకపోతే, Git దాన్ని మళ్లీ duplicate చేయదు; మునుపటి కమిట్లో ఉన్న blob objectనే సూచిస్తుంది. దీన్నే structural sharing అంటారు.
graph TD
subgraph "A Git Commit Object"
C[Commit Object<br>Hash: 8a4c10...] -->|Points to| T[Root Tree Object<br>Hash: 4a2b99...]
C -->|Points to| P[Parent Commit Hash<br>Hash: 55a420...]
C -.->|Metadata| M[Author, Committer, Timestamp, Message]
end
కమిట్ ఆబ్జెక్ట్ నిర్మాణం
కమిట్ను లోపల structured metadata ఉన్న సాధారణ plaintext fileగా సూచిస్తారు. Git ఈ plaintextను SHA-1తో hash చేసినప్పుడు, 40-character hex identifierను రూపొందిస్తుంది.
Raw commit objectలో ఈ fields ఉంటాయి:
- tree: repository root directoryను సూచించే top-level (root) tree objectకు pointer (hash).
- parent: మునుపటి కమిట్ (లేదా కమిట్ల) hash.
- ప్రారంభ కమిట్కు parent ఉండదు.
- సాధారణ కమిట్కు ఒక parent ఉంటుంది.
- merge commitకు రెండు లేదా అంతకంటే ఎక్కువ parents ఉంటాయి.
- author: కోడ్ రాసిన వ్యక్తి పేరు, email, Unix timestamp.
- committer: కోడ్ను commit చేసిన వ్యక్తి పేరు, email, Unix timestamp (ఉదాహరణకు, maintainer ఒక patchను apply చేసినప్పుడు).
- gpgsig: (Optional) కమిట్ sign చేసినట్లయితే cryptographic signature.
- message: మార్పులు ఎందుకు చేశారో వివరించే text description.
.git/లోపల ఏమి జరుగుతుంది? (ప్రయోగాత్మక పరిశీలన)
Git ఈ tree మరియు commit objectsను దశలవారీగా ఎలా నిర్మిస్తుందో repository లోపలికి వెళ్లి చూద్దాం.
దశ 1: ఫైల్ను stage చేసి indexను తనిఖీ చేయండి
ముందుగా repository initialize అయి ఉందని, git addతో ఒక ఫైల్ staged అయిందని నిర్ధారించుకుందాం.
$ mkdir git-commit-demo && cd git-commit-demo
$ git init
Initialized empty Git repository in /git-commit-demo/.git/
$ echo "console.log('hello world');" > app.js
$ git add app.js
ఇప్పుడు ఫైల్ blob objectగా compress అయి .git/index ఫైల్లో నమోదు అవుతుంది. చూద్దాం:
$ git ls-files --stage
100644 6be02374db118b9fb99cd98c6b403e5a558d0d57 0 app.js
40-character hash 6be02374db118b9fb99cd98c6b403e5a558d0d57 అనేది console.log('hello world'); ఉన్న blobకు Git SHA-1 ID (27 bytesకు, echo రాసిన newline కలిపి మొత్తం 28 bytes). మీ editor లేదా shell ఆ లైన్ను వేరుగా రాస్తే blob hash కూడా మారుతుంది — content addressingలో hash ఫైల్లోని exact bytes ఆధారంగా లెక్కించబడుతుంది.
ఈ పాఠంలోని hashes గురించి గమనిక: పైన ఉన్న
app.jsblob hash (6be02374…) exactగా, మళ్లీ పొందగలిగేదిగా ఉంటుంది, ఎందుకంటే blob కేవలం file contentపైనే ఆధారపడుతుంది. Commit మరియు tree hashesలో author/committer timestamps, timezone ఉంటాయి. అందుకే కింది outputsలో చూపిన సంక్షిప్త commit hashes (ఉదా.d4a123f) ప్రతినిధి విలువలు మాత్రమే. కొత్త repositoryలో ఇవే commands అమలు చేస్తే అదే structure వస్తుంది, కానీ commit మరియు tree IDs వేరుగా ఉంటాయి.
దశ 2: ఒక కమిట్ సృష్టించండి
ఇప్పుడు మన మొదటి commit రాద్దాం.
$ git commit -m "feat: introduce logging script"
[main (root-commit) d4a123f] feat: introduce logging script
1 file changed, 1 insertion(+)
create mode 100644 app.js
.git/refs/heads/లోని branch referencesను చూద్దాం. active branch file mainలో ఇప్పుడు commit యొక్క పూర్తి 40-character hash ఉండాలి:
$ cat .git/refs/heads/main
d4a123f4c7b8d80c0ef14815a5bb1d6a362bf2c9
ఏ branch activeగా ఉందో .git/HEAD Gitకు చెబుతుంది:
$ cat .git/HEAD
ref: refs/heads/main
దశ 3: కమిట్ ఆబ్జెక్ట్ను విడదీయడం
plumbing command git cat-fileతో సృష్టించిన commit objectను పరిశీలిద్దాం:
# Print type of the object
$ git cat-file -t d4a123f4c7b8d80c0ef14815a5bb1d6a362bf2c9
commit
# Print raw content of the commit object
$ git cat-file -p d4a123f4c7b8d80c0ef14815a5bb1d6a362bf2c9
tree b8a27d0ef093ab7e20cf7b68a417534431e21b7b
author Purna Pattela <purna@example.com> 1772960000 +0000
committer Purna Pattela <purna@example.com> 1772960000 +0000
feat: introduce logging script
కమిట్ ఆబ్జెక్ట్లో file content లేదా diff ఉండదని గమనించండి. అది b8a27d0... hash ఉన్న tree objectను సూచిస్తుంది. ఆ treeను చూద్దాం:
$ git cat-file -p b8a27d0ef093ab7e20cf7b68a417534431e21b7b
100644 blob 6be02374db118b9fb99cd98c6b403e5a558d0d57 app.js
Tree object directory listingలా పనిచేస్తుంది. ఇది filename app.jsను file permissions (100644) మరియు zlib-compressed content blob (6be0237...)తో map చేస్తుంది.
దశ 4: subdirectories జోడించి parentsను నిర్ధారించడం
Git nested foldersను ఎలా handle చేస్తుందో చూడటానికి ఒక subdirectory జోడిద్దాం.
$ mkdir src
$ echo "const port = 3000;" > src/config.js
$ git add src/config.js
$ git commit -m "chore: add source config"
[main 7f2b58c] chore: add source config
1 file changed, 1 insertion(+)
create mode 100644 src/config.js
ఈ రెండో commitను చదువుదాం:
$ git cat-file -p 7f2b58c
tree a832dbf521b4a56c071d2b512c98a3e74211a512
parent d4a123f4c7b8d80c0ef14815a5bb1d6a362bf2c9
author Purna Pattela <purna@example.com> 1772960100 +0000
committer Purna Pattela <purna@example.com> 1772960100 +0000
chore: add source config
కొత్త లైన్ parent d4a123f...ను గమనించండి. ఇది మొదటి commitవైపు తిరిగి చూపుతూ వాటిని history chainలో కలుపుతుంది.
ఈ కొత్త commitలోని treeను చూద్దాం:
$ git cat-file -p a832dbf521b4a56c071d2b512c98a3e74211a512
100644 blob 6be02374db118b9fb99cd98c6b403e5a558d0d57 app.js
040000 tree f3b3a3c9e6db5832a875a6c11d2b270a2936274b src
Flat file list చూపించడానికి బదులుగా, root tree object మరో tree object (అంటే src/ directory; ఇది 040000 modeతో సూచించబడుతుంది) వైపు చూపిస్తుంది. Nested src treeలోకి చూస్తే:
$ git cat-file -p f3b3a3c9e6db5832a875a6c11d2b270a2936274b
100644 blob c8384df24a5611dfd9a1db4b86270a1a8a25c156 config.js
ఈ tree-within-a-tree architecture మీ filesystemను సరిగ్గా ప్రతిబింబిస్తుంది.
వివరణాత్మక కమాండ్ ఎంపికలు మరియు అధునాతన వినియోగం
1. చివరి commitను amend చేయడం (git commit --amend)
మీ commit messageలో typo ఉంటే, లేదా commit చేయడానికి ముందు మార్పును stage చేయడం మరిచిపోతే, చివరి commitను amend చేయవచ్చు:
$ git add forgotten_file.txt
$ git commit --amend -m "chore: add source config and settings"
తెర వెనుక: Gitలో commits immutable (వాటి contents ఆధారంగా SHA-1 hash లెక్కించబడుతుంది) కాబట్టి ఇప్పటికే ఉన్న commitను Git edit చేయలేదు. బదులుగా, --amend కొత్త tree మరియు మార్చిన messageను సూచించే brand-new commit objectను సృష్టిస్తుంది; దాని parent పాత commitకు ఉన్న parentగా ఉంటుంది. తర్వాత Git branch pointerను కొత్త commitవైపు update చేస్తుంది, పాత commit orphanedగా మిగులుతుంది.
graph TD
subgraph "How Amend Works"
C1[Commit 1] --> C2[Commit 2: Original]
C1 --> C3[Commit 3: Amended]
Branch[Branch Ref: main] -->|Moved from C2 to C3| C3
end
style C2 fill:#faa,stroke:#333
style C3 fill:#afa,stroke:#333
2. Staging Areaను దాటేయడం (git commit -a)
-a (లేదా --all) flagతో stagingను దాటేయవచ్చు. ఇది modified మరియు deleted files అన్నింటినీ ఆటోమేటిక్గా stage చేసి, వెంటనే commit రాయమని Gitకు చెబుతుంది:
$ git commit -am "refactor: simplify logger interface"
[!WARNING] ఈ command కొత్తగా untrackedగా ఉన్న filesను stage చేయదు. మీరు brand-new file సృష్టిస్తే,
git commit -aకు ముందు తప్పనిసరిగాgit addఅమలు చేయాలి.
3. GPG లేదా SSHతో commits sign చేయడం (git commit -S)
Production environmentsలో, commits జాబితాలో ఉన్న author నుంచే నిజంగా వచ్చాయని నిర్ధారించడం చాలా ముఖ్యం. మీరు commitsను cryptographically sign చేయవచ్చు:
$ git commit -S -m "feat: release critical payment gateway integration"
ఇది local private keyను ఉపయోగించి commitను sign చేస్తుంది. GitHub లేదా GitLab మీ public keyతో signatureను match చేసి commit పక్కన “Verified” badge చూపించగలవు.
వాస్తవ పరిస్థితి: atomic commits రాయడం
ఆరోగ్యకరమైన codebase atomic commitsపై ఆధారపడుతుంది. Atomic commit అంటే ఒకటే logical పని చేసే commit. ఒక featureను అమలు చేయడానికి లేదా ఒక bugను పరిష్కరించడానికి అవసరమైన అన్ని మార్పులు అందులో ఉండాలి; అంతకు మించి ఏదీ ఉండకూడదు.
ఉదాహరణకు, authentication system నిర్మిస్తున్నప్పుడు implemented login and fixed layout issues on homepageలాంటి commit message రాయకండి. Homepage layout fix వల్ల మరేదైనా విరిగితే, ఆ commitను revert చేయడం login systemను కూడా తొలగిస్తుంది!
బదులుగా, git add ఉపయోగించి పనిని విడగొట్టి separate commits చేయండి:
# First, stage only the layout changes
$ git add src/styles.css
$ git commit -m "fix(styles): repair home page navigation alignment"
# Next, stage the login files
$ git add src/auth/
$ git commit -m "feat(auth): implement user authentication mechanism"
ఈ clean structureతో git log ఉపయోగించి historyని audit చేయడం సులభమవుతుంది. ఇప్పుడు, developers సమస్యలను సురక్షితంగా వేరు చేయగలరు.
సాధారణ సమస్యలు, తప్పులు
1. Pushed commitsను amend చేయడం
ఇతర developersతో share చేసిన remote repository (ఉదా. GitHub)కి ఇప్పటికే push చేసిన commitపై ఎప్పుడూ git commit --amend అమలు చేయకండి.
- ఎందుకు: Amend చేయడం వల్ల commit hash మారుతుంది. ఈ amended commitను force-push చేస్తే అందరి history overwrite అవుతుంది; వారు pull చేసినప్పుడు ఇబ్బందికరమైన merge conflicts వస్తాయి.
- సాధారణ నియమం: మీ local computerలో మాత్రమే ఉన్న commitsను amend చేయండి.
2. ఖాళీ కమిట్ లోపం
Stage చేసిన మార్పులు ఏవీ లేకుండా git commit అమలు చేయడానికి ప్రయత్నిస్తే Git commandను reject చేస్తుంది:
$ git commit -m "nothing changes"
On branch main
nothing to commit, working tree clean
- పరిష్కారం: file modifications లేకుండానే commit సృష్టించాల్సిన అవసరం నిజంగా ఉంటే (ఉదాహరణకు CI/CD build runnerను trigger చేయడానికి), override flag ఉపయోగించండి:
$ git commit --allow-empty -m "trigger: run test suite in pipeline"
3. Author మరియు Committer మధ్య గందరగోళం
కొన్ని project historiesలో Authorగా ఒకరిని, Committerగా మరొకరిని చూపించే commit కనిపించవచ్చు.
- Author: అసలు code changes రాసిన వ్యక్తి.
- Committer: commitను apply చేసిన వ్యక్తి (ఉదా.
git rebaseఉపయోగించడం లేదా patch apply చేయడం). - సాధారణంగా ఇద్దరూ ఒకరే. అయితే, మీరు వేరొకరి pull requestను GitHubలో rebase లేదా squash చేస్తే, మీరు Committer అవుతారు; వారు Authorగానే ఉంటారు.
కమాండ్ల త్వరిత సూచన
| Command | Action |
|---|---|
git commit | multi-line commit message రాయడానికి మీ terminal editorను తెరుస్తుంది. |
git commit -m "msg" | staged changesను చిన్న inline messageతో commit చేస్తుంది. |
git commit -a -m "msg" | modified/deleted ఫైళ్లను stage చేసి ఒకే దశలో commit చేస్తుంది. |
git commit --amend | చివరి commitను amend చేస్తుంది (కొత్త staged ఫైళ్లను జోడిస్తుంది మరియు/లేదా messageను update చేస్తుంది). |
git commit --amend --no-edit | కొత్త filesతో చివరి commitను amend చేస్తుంది, కానీ exact అదే messageను ఉంచుతుంది. |
git commit --allow-empty -m "msg" | staged లేదా modified changes ఏవీ లేకపోయినా commitను force చేస్తుంది. |
git commit -S -m "msg" | commitను cryptographically sign చేస్తుంది. |
FAQ (ఇతరులు తరచుగా అడిగే ప్రశ్నలు)
git commit మరియు git push మధ్య తేడా ఏమిటి?
git commit local command. ఇది మీ local directory database (.git/objects/)లో ఒక snapshotను నమోదు చేస్తుంది. ఇది ఏ external serverను సంప్రదించదు. git push network command; ఇది ఈ local commits, trees, blobsను remote repository (ఉదా. GitHub, GitLab లేదా self-hosted server)కి upload చేస్తుంది, తద్వారా వాటిని ఇతరులతో share చేయవచ్చు.
Git 40 అక్షరాల commit hashను ఎలా లెక్కిస్తుంది?
Git commit objectలోని header మరియు contentను SHA-1తో hash చేస్తుంది. Contentలో tree hash, parent hash(es), author info, committer info, commit message ఉంటాయి. Hash calculationలో ప్రస్తుత timestamp కూడా ఉండటంతో, files మరియు message పూర్తిగా ఒకటే ఉన్నా వేర్వేరు సమయాల్లో సృష్టించిన రెండు commitsకు వేర్వేరు hashes వస్తాయి.
నా చివరి commitను revert లేదా delete చేయవచ్చా?
అవును. మీరు changes commit చేసినా, commitను undo చేసి changesను working directoryలో ఉంచాలనుకుంటే (వాటిని unstage చేస్తూ), ఇలా అమలు చేయండి:
git reset --soft HEAD~1
చివరి commitను పూర్తిగా తొలగించి అన్ని modificationsను discard చేయాలనుకుంటే:
git reset --hard HEAD~1
(హెచ్చరిక: git reset --hardను సులభంగా undo చేయలేరు; అమలు చేయడానికి ముందు మీ పనిని తనిఖీ చేయండి!)
Detached HEAD స్థితి అంటే ఏమిటి?
ఒక branchకు బదులుగా నిర్దిష్ట commit hashను checkout చేస్తే (ఉదా. git checkout a1b2c3d - link git-checkout), మీ HEAD pointer branch referenceకు కాకుండా నేరుగా commit objectకు చూపుతుంది. ఈ స్థితిలో commit చేస్తే, కొత్త commitవైపు ఏ branch కూడా చూపదు. మీరు branches మార్చితే, కొత్త commit orphanedగా మారి చివరికి Git garbage collection ద్వారా తొలగించబడుతుంది. Commit చేయడానికి ముందు మీరు branchలో ఉన్నారని ఎప్పుడూ నిర్ధారించుకోండి (link git-branch).
మీ జ్ఞానాన్ని పరీక్షించుకోండి
క్విజ్ లోడ్ అవుతోంది…