搜尋

首頁  >  問答  >  主體

如何解決git 2個地方的程式碼不一致.

初始情況是, a和b的程式碼庫是完全相同的.

1, a修改了代碼.然後成功push到 bitbucket
2, a做了更改是: 程式中的目錄app/storage/sessions/剛開始沒有加入到.gitignore中,所以a在.gitignore中加了這個目錄.其它的是一些程序的代碼.
3, b本身有程式碼,但沒有修改.因為a更新了,所以b進行pull操作,可能是因為.gitignore衝突,git有提示到git reset --hard這一句,以為是會重置(reset這英文),就選了另一項(忘了選了什麼),然後進行平常的pull,commit,提示pull到bitbucket成功了,但看代碼卻沒有看到a所做的更改.沒在意,b就繼續修改程式碼,push到遠端.b這邊提示這個.

b以為自已看懂了,選了
$ git add --ignore-removal app/storage/sessions/

然後..上bitbucket一看,發現剛才a所做的更改全被刪除了..

例如:像圖片中這些是a加入的東西, 還有很多其他的代碼,...現在全被刪除掉了..

怎麼恢復a成功push的更改,同時也保留b的這次更改呢? a的commit有160個文件改動,b的也有60多...除了a和b2人商討根據代碼一條條的對照思路進行恢復,有沒有比較好的方案呢? 謝謝啦...


更新:

依照@nightire的回答, a這邊進行瞭如下操作

# git add .
# git commit -m "big wrong! for last your git-commits"
On branch php-v0.0.1
Your branch is up-to-date with 'origin/php-v0.0.1'.

nothing to commit, working directory clean

所以,a修改了一個檔案,加了一個空白行,然後重新# git push --force orgin php-v0.0.1:php-v0.0.1

接著,b這邊進行如下操作

$ git pull origin php-v0.0.1:php-v0.0.1
Password for 'https://Deloz@bitbucket.org':
remote: Counting objects: 15, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 4), reused 2 (delta 0)
Unpacking objects: 100% (6/6), done.
From https://bitbucket.org/deloz/xxxxx
 ! [rejected]        php-v0.0.1 -> php-v0.0.1  (non-fast-forward)
 + c344522...14bd65e php-v0.0.1 -> origin/php-v0.0.1  (forced update)

好像b又操作錯了,這分支好像不對呀,然後b又來了一次不加參數了pull,如下

$ git pull
Password for 'https://Deloz@bitbucket.org':
Merge made by the 'recursive' strategy.
 app/database/migrations/xxxxxx.php | 1 +
 1 file changed, 1 insertion(+)

此時,b這邊仍然沒有a加入的文件和a之前(b出錯前,a修改並push成功的代碼)的修改.(這次a是加了一個空行,b這邊也成功反映出來了.)...


再更新:

根據大家的看法和方案
a操作

# git log --pretty=oneline
14bd65ee1b14c1f06be98b22bc6cb5feb2039656 big wrong! for last your git-commits
3c96695b53f7d4e8dd78c9025044cea1d4cc0472 这个是正确的时候a所push的
00f0cdd6b8861d64a7930b823f552888edebdc11 xxxxxxxxxx
668fde30ad1d5d76b550f572ba6b64ae14a1e715 xxxxxx
8a80bb0eb9387db68119bbd7e0d15677ed7aa1f1 xxxxx
7ca8599be1ceb1dde6766315543209bf1bb761ce xxxxx^
bba184c4f324ed99b3fb580c103aba3505a688a5 xxxxxxxxx
458182037cfa54b8447b617c119d134ada250462 xxxxxxxxx
0029b46ac999f2c4d59c8cfb194ed1c2653fa1f4 xxxxxxn

b使用了git revert commit,程式碼沒回滾到正確的commit去..應該是用錯了..

$ git log --pretty=oneline
06661f005bc306796d2101633f68c2d01cd6bac3 re push (b push上来的)
3e34c6f8c177c67d487c7858720ac383e77738e2 Revert "Revert "big wrong! for last you  (b push上来的)
bcf07a9836aaaa9bdd505094b0859c13322f4519 Revert "big wrong! for last your git-co (b push上来的)
885c117de5ef67f430e0d3f8b0b1647a1cd14ee8 Merge branch 'php-v0.0.1' of https://bi (b push上来的)
14bd65ee1b14c1f06be98b22bc6cb5feb2039656 big wrong! for last your git-commits(a加空行后 push上来的)
c344522e2cba0e85e4b14393d596b992d47f1821 add column to table  (b push上来的)
3c96695b53f7d4e8dd78c9025044cea1d4cc0472 这个是正确的时候a所push的
00f0cdd6b8861d64a7930b823f552888edebdc11 xxxxxxxxxx
668fde30ad1d5d76b550f572ba6b64ae14a1e715 xxxxxx
8a80bb0eb9387db68119bbd7e0d15677ed7aa1f1 xxxxx
7ca8599be1ceb1dde6766315543209bf1bb761ce xxxxx^
bba184c4f324ed99b3fb580c103aba3505a688a5 xxxxxxxxx
458182037cfa54b8447b617c119d134ada250462 xxxxxxxxx
0029b46ac999f2c4d59c8cfb194ed1c2653fa1f4 xxxxxxn

接著
a執行

//备份一下当前a的分支
# git branch php_backup

//把a的分支回滚到 3c96695b53f7d4e8dd78c9025044cea1d4cc0472  因为上一次操作是 push --force了...
# git reset --hard 3c96695b53f7d4e8dd78c9025044cea1d4cc0472
HEAD is now at 3c96695 change some views

//删除远程的bitbucket上的分支
# git push origin :php-v0.0.1
Password for 'https://deloz@bitbucket.org':
To https://deloz@bitbucket.org/deloz/xxx.git
 - [deleted]         php-v0.0.1

//把正确的3c96695b53f7d4e8dd78c9025044cea1d4cc0472, push到远程bitbucket上
# git push origin php-v0.0.1
Password for 'https://deloz@bitbucket.org':
Counting objects: 256, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (220/220), done.
Writing objects: 100% (256/256), 785.09 KiB | 0 bytes/s, done.
Total 256 (delta 64), reused 158 (delta 26)
To https://deloz@bitbucket.org/deloz/xxx.git
 * [new branch]      php-v0.0.1 -> php-v0.0.1

然後, 根據@Guang Chen的方法, b操作

//备份一下B的分支
$ git branch php_bbbb
//把b的分支回滚到 3c96695b53f7d4e8dd78c9025044cea1d4cc0472
$ git reset --hard 3c96695b53f7d4e8dd78c9025044cea1d4cc0472
$ git fetch origin
$ git rebase origin/php-v0.0.1

//看一下log, b和a的一样的状态了.
$ git log --pretty=oneline
3c96695b53f7d4e8dd78c9025044cea1d4cc0472 这个是正确的时候a所push的
00f0cdd6b8861d64a7930b823f552888edebdc11 xxxxxxxxxx
668fde30ad1d5d76b550f572ba6b64ae14a1e715 xxxxxx
8a80bb0eb9387db68119bbd7e0d15677ed7aa1f1 xxxxx
7ca8599be1ceb1dde6766315543209bf1bb761ce xxxxx^
bba184c4f324ed99b3fb580c103aba3505a688a5 xxxxxxxxx
458182037cfa54b8447b617c119d134ada250462 xxxxxxxxx
0029b46ac999f2c4d59c8cfb194ed1c2653fa1f4 xxxxxxn


$ git status
On branch php-v0.0.1
Your branch is up-to-date with 'origin/php-v0.0.1'.

nothing to commit, working directory clean

剩下的就是分支php_bbb裡邊的不同程式碼...
使用git diff php-v0.0.1 php_bbbb >> 11.txt ,讓b去修改了...
(/ □ )

黄舟黄舟2772 天前1035

全部回覆(3)我來回復

  • 阿神

    阿神2017-04-25 09:05:31

    你的b在pull origin master之前,是有一個commit的例如abcde

    # 在b机器上
    $ git reset abcde --hard 
    

    回到b pull之前的樣子
    然後因為你的a始終沒有pull過,所以現在可以認為回到了你最初的樣子,除了a提交的一個添加空行的提交

    也就是說你現在應該和在2是一樣的狀態。
    這時你的b也是乾淨的工作區(沒有unstaged change)
    如果你確信現在確實是和2中是一個狀態,那麼在b上執行

    $ git fetch origin
    $ git rebase origin/php-v0.0.1 
    

    這時會提醒你有衝突,例如.gitignore
    然後開啟.gitignore文件,解決衝突,再執行

    $ git add .gitignore #添加解决了冲突的文件
    $ git commit #直接:wq即可
    

    如果在rebase過程中,有什麼意外情況,請不要隨意操作,透過git rebase --abort放棄,然後再補充問題

    回覆
    0
  • 怪我咯

    怪我咯2017-04-25 09:05:31

    我覺得沒那麼複雜啊…

    A,本地的最近更新還是 OK 的吧?我的意思是 B 最後 push 之後,A 沒有 pull 吧?如果是這樣,讓 A 直接 push --force,覆蓋掉 B 最後的 push,然後 B 重新 pull,這次不要弄錯了,以後就好了。

    如果 A 已經 pull 過最新的(也就是錯誤的)程式碼,那就在本地 reset 到原本應該正確的那裡,然後重複上面的事情就好。

    總而言之一句話,分散式的好處就是不管 central repo 亂成啥,你想要的那些 commits 總是能找回來。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-25 09:05:31

    因為看暈了,也不太習慣git指令行,具體回答就不做了。

    我只想說,這種場景下,git pull这条命令就不应该用,fetch & rebase才是正道

    另外不如說,Git的使用姿勢更有問題

    • 兩個人同時在一條分支裡開發這件事有問題,大多數情況都應該是各自在各自的feature branch當中玩,自己的未完工的功能就應該在自己的分支裡,拉別人的代碼應該永遠不影響自己的分支。
    • 一個commit超過10個檔案有問題。或者從時間上看,超過半天的編碼工作沒有提交有問題

    比起解決現有程式碼亂掉(這是小事,總是能解決的),團隊內普及正確的git姿勢才是更重要的

    參考: 一個成功的Git分支模型 http://www.juvenxu.com/2010/11/28/a-successful-git-branching-model/

    回覆
    0
  • 取消回覆