Зрабіць бягучую фіксацыю адзінай (пачатковай) фіксацыяй у рэпазітары Git?

У цяперашні час у мяне ёсць лакальны рэпазітар Git, які я націскаю на рэпазітар Github.

Лакальны рэпазітар мае ~ 10 камітаў, а рэпазітар Github з'яўляецца сінхранізаваць дублікатам гэтага.

Што б я хацеў зрабіць, гэта выдаліць УСЕ гісторыю версій з лакальнага рэпазітара Git, так што бягучае змесціва рэпазітара будзе адлюстроўвацца як адзінае камітаў (і, такім чынам, больш старыя версіі файлаў у рэпазітары не захоўваюцца),

Я хацеў бы націснуць гэтыя змены ў Github.

Я даследаваў Git rebase, але гэта, падобна, больш падыходзіць для выдалення пэўных версій. Яшчэ адно патэнцыйнае рашэнне - выдаліць лакальнае РЭПО і стварыць новы, хоць гэта, верагодна, стварыла б шмат працы!

ETA: Існуюць пэўныя каталогі / файлы, якія не адсочваюцца - калі магчыма, я хацеў бы падтрымліваць адключэнне гэтых файлаў.

460
13 марта '12 в 14:41 2012-03-13 14:41 зададзены kaese 13 сакавіка '12 у 14:41 2012-03-13 14:41
@ 14 адказаў

Тут падыход грубай сілы. Ён таксама выдаляе канфігурацыю рэпазітара.

Заўвага. Гэта НЕ працуе, калі ў рэпазітары ёсць подмодули! Калі вы выкарыстоўваеце подмодули, вы павінны выкарыстоўваць, напрыклад, інтэрактыўная перазагрузка

Крок 1: выдаліце ўсю гісторыю (Пераканайцеся, што ў вас ёсць рэзервовая копія, гэта немагчыма вярнуць)

 rm -rf .git 

Крок 2: адновіце рэпазітар Git толькі з бягучым кантэнтам

 git init git add . git commit -m "Initial commit" 

Крок 3: націсніце на GitHub.

 git remote add origin <github-uri> git push -u --force origin master 
747
13 марта '12 в 14:44 2012-03-13 14:44 адказ дадзены Fred Foo 13 сакавіка '12 у 14:44 2012-03-13 14:44

Адзінае рашэнне, якое працуе для мяне (і працуе подмодулей) -

 git checkout --orphan newBranch git add -A # Add all files and commit them git commit git branch -D master # Deletes the master branch git branch -m master # Rename the current branch to master git push -f origin master # Force push master branch to github git gc --aggressive --prune=all # remove the old files 
border=0

Выдаленне .git/ заўсёды выклікае вялізныя праблемы, калі ў мяне ёсць подмодули. Выкарыстанне git rebase --root нейкім чынам выкліча для мяне канфлікты (і ў мяне шмат гісторыі).

410
27 окт. адказ дадзены Zeelot 27 каст. 2012-10-27 21:16 '12 а 21:16 2012/10/27 21:16

Гэта мой спрыяльны падыход:

 git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree}) 

Гэта створыць новую галінку з адной фіксацыяй, якая дадасць усё ў HEAD. Ён нічога не мяняе, таму ён цалкам бяспечны.

63
22 марта '13 в 16:53 2013-03-22 16:53 адказ дадзены dan_waterworth 22 сакавіка '13 у 16:53 2013/03/22 16:53

Іншым варыянтам, які можа апынуцца вялікі працай, калі ў вас шмат камітаў, з'яўляецца інтэрактыўная rebase (калі ваша версія git равнa> 1,7.12): git rebase --root -i

Пры прадстаўленні спісу камітаў ў вашым рэдактары:

  • Зменіце "pick" на "reword" для першага фіксацыі
  • Зменіце "pick" на "fixup" кожны іншы commit

Захаваць і закрыць. git пачне перазагружацца.

У канцы ў вас будзе новы каранёвай фіксатар, які з'яўляецца камбінацыяй усіх тых, якія прыйшлі пасля яго.

Перавага ў тым, што вам не трэба выдаляць ваш рэпазітар, і калі ў вас ёсць іншыя думкі, у вас заўсёды ёсць рэзерв.

Калі вы сапраўды хочаце знішчыць сваю гісторыю, reset master для гэтага фіксацыі і выдаліць усе астатнія галіны.

26
14 марта '12 в 23:24 2012-03-14 23:24 адказ дадзены Carl 14 сакавіка '12 у 23:24 2012-03-14 23:24

Выдаліць тэчку .git можа прывесці да праблем у рэпазітары git. Калі вы хочаце выдаліць ўсю сваю гісторыю фіксацыі.

выканайце наступныя дзеянні:

крок-1 (checkout)

 git checkout --orphan latest_branch 

step-2 (дадайце ўсе файлы)

 git add -A 

Крок 3 (Зафіксуйце змены)

 git commit -am "commit message" 

step-4 (Выдаліць галіна)

 git branch -D master 

step-5 (пераназавіце бягучую галіну на майстар)

 git branch -m master 

Крок 6 (канчатковы крок, сіла для абнаўлення вашага рэпазітара)

 git push -f origin master 

!! Цяпер атрымлівайце асалоду ад гісторыяй фіксацыі!

21
14 окт. адказ дадзены Shivam Srivastava 14 каст. 2017-10-14 12:08 '17 у 12:08 2017/10/14 00:08

Варыянт прапанаванага метаду larsmans:

Захавайце спіс прывесці якія тут немагчыма файлаў:

 git ls-files --others --exclude-standard > /tmp/my_untracked_files 

Захавайце канфігурацыю git:

 mv .git/config /tmp/ 

Затым выканаеце першыя крокі larsmans:

 rm -rf .git git init git add . 

Адновіце канфігурацыю:

 mv /tmp/config .git/ 

Адмоўцеся ад неправераных файлаў:

 cat /tmp/my_untracked_files | xargs -0 git rm --cached 

Затым зафіксуйце:

 git commit -m "Initial commit" 

І, нарэшце, націсніце на свой рэпазітар:

 git push -u --force origin master 
14
19 апр. адказ дадзены lalebarde 19 крас. 2014-04-19 11:58 '14 г. у 11:58 2014/04/19 11:58

Стварыце галіна, скапіруйце ўсё змесціва ў яе, скапіруйце яе і затым выдаліце ​​галоўную галіну:

 git checkout --orphan newBranch; git add -A ;git commit -am 'first commit' ;git branch -D master;git branch -m master; git push -f origin master; git gc --aggressive --prune=all 
5
12 марта '17 в 17:53 2017-03-12 17:53 адказ дадзены pratik_bhavsar 12 сакавіка '17 у 17:53 2017/03/12 17:53

Вы можаце выкарыстоўваць неглыбокія клоны (git> 1.9):

 git clone --depth depth remote-url 

Дадатковая літаратура: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/

5
04 апр. адказ дадзены Matthias M 04 крас. 2016-04-04 14:05 '16 у 14:05 2016/04/04 14:05

Метад ніжэй прайграваны, таму няма неабходнасці запускаць клон зноў, калі абодва бакі ўзгодненыя, проста запусціце script з іншага боку.

 git log -n1 --format=%H >.git/info/grafts git filter-branch -f rm .git/info/grafts 

Калі вы хочаце яго ачысціць, паспрабуйце script:

http://sam.nipl.net/b/git-gc-all-ferocious

Я напісаў script, які "забівае гісторыю" для кожнай галінкі ў рэпазітары:

http://sam.nipl.net/b/git-kill-history

гл. таксама: http://sam.nipl.net/b/confirm

2
06 февр. адказ дадзены Sam Watkins 06 февр. 2013-02-06 19:46 '13 у 19:46 2013/02/06 19:46
 git for-each-ref --format='git update-ref -d %(refname)' \ refs/{heads,tags} | sh -x current=$(git commit-tree -m 'Initial commit' `git write-tree`) git update-ref -m 'Initial commit' `git symbolic-ref HEAD` $current 

Гэта прывядзе да выдалення ўсіх лакальных галін і тэгаў, зробіць адна падзея без гісторыі са станам вашай бягучай праверкі ў любы галінкі бягучай і пакіне ўсё астатняе ў вашым РЭПО некранутым. Затым вы можаце прымусова націснуць на свае пульты, як вам падабаецца.

1
05 апр. адказ дадзены jthill 05 крас. 2014-04-05 04:42 '14 у 04:42 2014/04/05 04:42

Што б я хацеў зрабіць, гэта выдаліць УСЕ гісторыю версій з лакальнага рэпазітара Git, так што бягучае змесціва рэпазітара будзе адлюстроўвацца як адзінае камітаў (і, такім чынам, больш старыя версіі файлаў у рэпазітары не захоўваюцца),

Больш канцэптуальны адказ:

git аўтаматычна смецце збірае старыя камітаў, калі тэгі / галінкі / спасылкі не паказваюць на іх. Такім чынам, вам проста трэба выдаліць усе тэгі / галінкі і стварыць новую сірочыя фіксацыю, звязаную з якой-небудзь галінкай - па пагадненні вы дазволіце галінцы master пазначыць на гэта commit.

Старыя, недаступныя камітаў ніколі больш не будуць заўважаныя кім-небудзь, калі яны не будуць капацца з нізкаўзроўневая камандамі Git. Калі гэтага дастаткова для вас, я проста спынюся на гэтым, і хай аўтаматычны GC зробіць гэта, калі захоча. Калі вы хочаце пазбавіцца ад іх адразу, вы можаце выкарыстоўваць git gc (магчыма, з --aggressive --prune=all ). Для аддаленага рэпазітара Git вам не ўдасца гэта зрабіць, калі толькі ў вас няма доступу да файлавай сістэме.

0
04 апр. адказ дадзены AnoE 04 крас. 2016-04-04 14:27 '16 у 14:27 2016/04/04 14:27

Для гэтага выкарыстоўвайце каманду Shallow Clone git clone --depth 1 URL - ён будзе кланаваць толькі бягучы HEAD рэпазітара

-1
23 авг. адказ дадзены kkarki 23 жнів. 2017-08-23 18:55 '17 у 18:55 2017/08/23 18:55

Каб выдаліць апошнюю фіксацыю з git, вы можаце проста запусціць

 git reset --hard HEAD^ 

Калі вы выдаляеце некалькі камітаў зверху, вы можаце запусціць

 git reset --hard HEAD~2 

каб выдаліць апошнія дзве камітаў. Вы можа павялічыць лік, каб выдаліць яшчэ больш камітаў.

Дадатковая інфармацыя тут

Git tutoturial тут прадастаўляе дапамогу па ачыстцы рэпазітара:

вы хочаце выдаліць файл з гісторыі і дадаць яго ў .gitignoreдля забеспячэння таго, каб ён не быў выпадкова паўтораны. Для нашых прыкладаў мы збіраецца выдаліць Rakefile з рэпазітара github gem.

 git clone https://github.com/defunkt/github-gem.git cd github-gem git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch Rakefile' \ --prune-empty --tag-name-filter cat -- --all 

Цяпер, калі мы выдалілі файл з гісторыі, хай мы гарантуем, што мы не рабіце гэта выпадкова.

 echo "Rakefile" >> .gitignore git add .gitignore git commit -m "Add Rakefile to .gitignore" 

Калі вы задаволеныя станам рэпазітара, вам трэба прымусова націсніце на змены, каб перазапісаць аддалены рэпазітар.

 git push origin master --force 
-1
05 июня '13 в 8:41 2013-06-05 08:41 адказ дадзены octoback 05 чэрвеня '13 у 08:41 2013/06/05 08:41

Я вырашыў аналагічную праблему, проста выдаліўшы тэчку .git з майго праекта і реинтегрировав з дапамогай кантролю версій праз IntelliJ. Заўвага. Папка .git схаваная. Вы можаце праглядзець яго ў тэрмінале з дапамогай ls -a , а затым выдаліць яго з дапамогай rm -rf .git .

-1
11 апр. адказ дадзены JB Lovell 11 крас. 2017-04-11 21:54 '17 у 21:54 2017/04/11 21:54

Іншыя пытанні па пазнаках або Задайце пытанне