如何处理git gc致命错误:坏对象refs / remotes / origin / HEAD错误:无法运行重新包装

时间:2016-05-10 17:25:22

标签: git

我在尝试垃圾收集时今天随机点击列表。

$ git gc
fatal: bad object refs/remotes/origin/HEAD
error: failed to run repack

我该如何处理?

11 个答案:

答案 0 :(得分:89)

我不明白这种情况的后果,但正如in this thread所建议的那样,当我遇到这种情况时,我只是做了

$ mv .git/refs/remotes/origin/HEAD /tmp

(保留它以防万一)然后

$ git gc

没有抱怨地工作;我没有遇到任何问题。

答案 1 :(得分:43)

我遇到的问题(与上面this comment中提到的@Stavarengo相同的问题)是默认的远程分支(在我的情况下是develop)已被删除,但仍然是在.git/refs/remotes/origin/HEAD中引用。

在我的编辑器中打开.git/refs/remotes/origin/HEAD显示了这一点:

ref: refs/remotes/origin/develop

仔细编辑它以指向我的新默认分支,一切都很顺利:

ref: refs/remotes/origin/master

让我感到惊讶的线索是,git prune正在显示此错误:

> git prune
warning: symbolic ref is dangling: refs/remotes/origin/HEAD

答案 2 :(得分:22)

我认为解决方案如下,因为这似乎有效,但事实证明并没有真正解决问题。

git remote set-head origin --auto

答案 3 :(得分:16)

看起来您的符号引用可能已损坏... 尝试使用默认分支替换它,如下所示: 例如,我的默认分支是 master

$ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/master
$ git fetch --prune
$ git gc

那应该解决它。

答案 4 :(得分:13)

感谢上帝我找到了这个 https://makandracards.com/chris-4/54101-fixing-a-git-repo

fatal: bad object refs/remotes/origin/HEAD
error: failed to run repack

如果上游分支已被移除并且您的原点指向它,则可能会发生这种情况。您可以通过运行来确认这一点:

cat .git/refs/remotes/origin/HEAD

如果它指向一个不存在的分支,运行:

git remote set-head origin --auto

关注

git gc

会修复它

答案 5 :(得分:12)

在看到特伦顿的回答之后,我查看了我的.git/refs/remotes/origin/HEAD,发现它还指向一个现已删除的旧分支。

但是我没有自己编辑文件,而是尝试了Ryan的解决方案:

git remote set-head origin --auto

它自动将文件设置为新分支,git gc之后工作正常。

答案 6 :(得分:3)

git update-ref -d [wrong reference here]

这将解决此问题。

对于上述问题,请使用以下代码:

git update-ref -d 'refs/remotes/origin/HEAD'

如果您遇到.git错误,如下所示:

error: bad ref for .git/logs/refs/remotes/origin/Dec/session-dynatrace-logs 6

您可以从以下引用开始复制路径:

git update-ref -d 'refs/remotes/origin/Dec/session-dynatrace-logs 6'

答案 7 :(得分:0)

如果您使用的是git工作树,请确保您正在执行

git worktree prune

运行前

git gc

我的工作树损坏了,这在删除损坏的工作树后似乎可以解决问题。 git prune本身似乎无效。

答案 8 :(得分:0)

对我来说,原因是在Windows中的压缩文件夹中工作。文件夹解压缩后,它破坏了打包文件,并引发了其他奇怪的问题,例如无法修剪不存在的分支。

唯一的解决方法是清除工作目录并再次克隆远程仓库。幸运的是,我仍然可以推送和拉取更新以确保没有丢失任何内容。现在一切都很好。

答案 9 :(得分:0)

当所有其他答案均失败时,只需重新启动计算机即可。

我遇到了OP的错误,并且在无关目录中的某些package com.example.confrencecalldemo; import android.os.Handler; import android.os.Message; import android.os.Trace; import android.telecom.DisconnectCause; import android.telecom.PhoneAccount; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; public class CallList { private static final int DISCONNECTED_CALL_SHORT_TIMEOUT_MS = 200; private static final int DISCONNECTED_CALL_MEDIUM_TIMEOUT_MS = 2000; private static final int DISCONNECTED_CALL_LONG_TIMEOUT_MS = 5000; private static final int EVENT_DISCONNECTED_TIMEOUT = 1; private static CallList sInstance = new CallList(); private final HashMap<String, CallHelper> mCallById = new HashMap<>(); private final HashMap<android.telecom.Call, CallHelper> mCallByTelecommCall = new HashMap<>(); private final HashMap<String, List<String>> mCallTextReponsesMap = Maps.newHashMap(); /** * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is * load factor before resizing, 1 means we only expect a single thread to * access the map so make only a single shard */ private final Set<Listener> mListeners = Collections.newSetFromMap( new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); private final HashMap<String, List<CallUpdateListener>> mCallUpdateListenerMap = Maps .newHashMap(); private final Set<CallHelper> mPendingDisconnectCalls = Collections.newSetFromMap( new ConcurrentHashMap<CallHelper, Boolean>(8, 0.9f, 1)); /** * Static singleton accessor method. */ public static CallList getInstance() { return sInstance; } /** * USED ONLY FOR TESTING * Testing-only constructor. Instance should only be acquired through getInstance(). */ CallList() { } public void onCallAdded(android.telecom.Call telecommCall) { Trace.beginSection("onCallAdded"); CallHelper call = new CallHelper(telecommCall); // Log.d(this, "onCallAdded: callState=" + call.getState()); if (call.getState() == CallHelper.State.INCOMING || call.getState() == CallHelper.State.CALL_WAITING) { onIncoming(call, call.getCannedSmsResponses()); } else { onUpdate(call); } Trace.endSection(); } public void onCallRemoved(android.telecom.Call telecommCall) { if (mCallByTelecommCall.containsKey(telecommCall)) { CallHelper call = mCallByTelecommCall.get(telecommCall); if (updateCallInMap(call)) { // Log.w(this, "Removing call not previously disconnected " + call.getId()); } updateCallTextMap(call, null); } } /** * Called when a single call disconnects. */ public void onDisconnect(CallHelper call) { if (updateCallInMap(call)) { // Log.i(this, "onDisconnect: " + call); // notify those listening for changes on this specific change notifyCallUpdateListeners(call); // notify those listening for all disconnects notifyListenersOfDisconnect(call); } } /** * Called when a single call has changed. */ public void onIncoming(CallHelper call, List<String> textMessages) { if (updateCallInMap(call)) { // Log.i(this, "onIncoming - " + call); } updateCallTextMap(call, textMessages); for (Listener listener : mListeners) { listener.onIncomingCall(call); } } public void onUpgradeToVideo(CallHelper call){ // Log.d(this, "onUpgradeToVideo call=" + call); for (Listener listener : mListeners) { listener.onUpgradeToVideo(call); } } /** * Called when a single call has changed. */ public void onUpdate(CallHelper call) { Trace.beginSection("onUpdate"); onUpdateCall(call); notifyGenericListeners(); Trace.endSection(); } /** * Called when a single call has changed session modification state. * * @param call The call. * @param sessionModificationState The new session modification state. */ public void onSessionModificationStateChange(CallHelper call, int sessionModificationState) { final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId()); if (listeners != null) { for (CallUpdateListener listener : listeners) { listener.onSessionModificationStateChange(sessionModificationState); } } } /** * Called when the last forwarded number changes for a call. With IMS, the last forwarded * number changes due to a supplemental service notification, so it is not pressent at the * start of the call. * * @param call The call. */ public void onLastForwardedNumberChange(CallHelper call) { final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId()); if (listeners != null) { for (CallUpdateListener listener : listeners) { listener.onLastForwardedNumberChange(); } } } /** * Called when the child number changes for a call. The child number can be received after a * call is initially set up, so we need to be able to inform listeners of the change. * * @param call The call. */ public void onChildNumberChange(CallHelper call) { final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId()); if (listeners != null) { for (CallUpdateListener listener : listeners) { listener.onChildNumberChange(); } } } public void notifyCallUpdateListeners(CallHelper call) { final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId()); if (listeners != null) { for (CallUpdateListener listener : listeners) { listener.onCallChanged(call); } } } /** * Add a call update listener for a call id. * * @param callId The call id to get updates for. * @param listener The listener to add. */ public void addCallUpdateListener(String callId, CallUpdateListener listener) { List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(callId); if (listeners == null) { listeners = new CopyOnWriteArrayList<CallUpdateListener>(); mCallUpdateListenerMap.put(callId, listeners); } listeners.add(listener); } /** * Remove a call update listener for a call id. * * @param callId The call id to remove the listener for. * @param listener The listener to remove. */ public void removeCallUpdateListener(String callId, CallUpdateListener listener) { List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(callId); if (listeners != null) { listeners.remove(listener); } } public void addListener(Listener listener) { Preconditions.checkNotNull(listener); mListeners.add(listener); // Let the listener know about the active calls immediately. listener.onCallListChange(this); } public void removeListener(Listener listener) { if (listener != null) { mListeners.remove(listener); } } /** * TODO: Change so that this function is not needed. Instead of assuming there is an active * call, the code should rely on the status of a specific CallHelper and allow the presenters to * update the CallHelper object when the active call changes. */ public CallHelper getIncomingOrActive() { CallHelper retval = getIncomingCall(); if (retval == null) { retval = getActiveCall(); } return retval; } public CallHelper getOutgoingOrActive() { CallHelper retval = getOutgoingCall(); if (retval == null) { retval = getActiveCall(); } return retval; } /** * A call that is waiting for {@link PhoneAccount} selection */ public CallHelper getWaitingForAccountCall() { return getFirstCallWithState(CallHelper.State.SELECT_PHONE_ACCOUNT); } public CallHelper getPendingOutgoingCall() { return getFirstCallWithState(CallHelper.State.CONNECTING); } public CallHelper getOutgoingCall() { CallHelper call = getFirstCallWithState(CallHelper.State.DIALING); if (call == null) { call = getFirstCallWithState(CallHelper.State.REDIALING); } return call; } public CallHelper getActiveCall() { return getFirstCallWithState(CallHelper.State.ACTIVE); } public CallHelper getBackgroundCall() { return getFirstCallWithState(CallHelper.State.ONHOLD); } public CallHelper getDisconnectedCall() { return getFirstCallWithState(CallHelper.State.DISCONNECTED); } public CallHelper getDisconnectingCall() { return getFirstCallWithState(CallHelper.State.DISCONNECTING); } public CallHelper getSecondBackgroundCall() { return getCallWithState(CallHelper.State.ONHOLD, 1); } public CallHelper getActiveOrBackgroundCall() { CallHelper call = getActiveCall(); if (call == null) { call = getBackgroundCall(); } return call; } public CallHelper getIncomingCall() { CallHelper call = getFirstCallWithState(CallHelper.State.INCOMING); if (call == null) { call = getFirstCallWithState(CallHelper.State.CALL_WAITING); } return call; } public CallHelper getFirstCall() { CallHelper result = getIncomingCall(); if (result == null) { result = getPendingOutgoingCall(); } if (result == null) { result = getOutgoingCall(); } if (result == null) { result = getFirstCallWithState(CallHelper.State.ACTIVE); } if (result == null) { result = getDisconnectingCall(); } if (result == null) { result = getDisconnectedCall(); } return result; } public boolean hasLiveCall() { CallHelper call = getFirstCall(); if (call == null) { return false; } return call != getDisconnectingCall() && call != getDisconnectedCall(); } public CallHelper getVideoUpgradeRequestCall() { for(CallHelper call : mCallById.values()) { if (call.getSessionModificationState() == CallHelper.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { return call; } } return null; } public CallHelper getCallById(String callId) { return mCallById.get(callId); } public CallHelper getCallByTelecommCall(android.telecom.Call telecommCall) { return mCallByTelecommCall.get(telecommCall); } public List<String> getTextResponses(String callId) { return mCallTextReponsesMap.get(callId); } /** * Returns first call found in the call map with the specified state. */ public CallHelper getFirstCallWithState(int state) { return getCallWithState(state, 0); } /** * Returns the [position]th call found in the call map with the specified state. * TODO: Improve this logic to sort by call time. */ public CallHelper getCallWithState(int state, int positionToFind) { CallHelper retval = null; int position = 0; for (CallHelper call : mCallById.values()) { if (call.getState() == state) { if (position >= positionToFind) { retval = call; break; } else { position++; } } } return retval; } /** * This is called when the service disconnects, either expectedly or unexpectedly. * For the expected case, it's because we have no calls left. For the unexpected case, * it is likely a crash of phone and we need to clean up our calls manually. Without phone, * there can be no active calls, so this is relatively safe thing to do. */ public void clearOnDisconnect() { for (CallHelper call : mCallById.values()) { final int state = call.getState(); if (state != CallHelper.State.IDLE && state != CallHelper.State.INVALID && state != CallHelper.State.DISCONNECTED) { call.setState(CallHelper.State.DISCONNECTED); call.setDisconnectCause(new DisconnectCause(DisconnectCause.UNKNOWN)); updateCallInMap(call); } } notifyGenericListeners(); } /** * Called when the user has dismissed an error dialog. This indicates acknowledgement of * the disconnect cause, and that any pending disconnects should immediately occur. */ public void onErrorDialogDismissed() { final Iterator<CallHelper> iterator = mPendingDisconnectCalls.iterator(); while (iterator.hasNext()) { CallHelper call = iterator.next(); iterator.remove(); finishDisconnectedCall(call); } } /** * Processes an update for a single call. * * @param call The call to update. */ private void onUpdateCall(CallHelper call) { // Log.d(this, "\t" + call); if (updateCallInMap(call)) { // Log.i(this, "onUpdate - " + call); } updateCallTextMap(call, call.getCannedSmsResponses()); notifyCallUpdateListeners(call); } /** * Sends a generic notification to all listeners that something has changed. * It is up to the listeners to call back to determine what changed. */ private void notifyGenericListeners() { for (Listener listener : mListeners) { listener.onCallListChange(this); } } private void notifyListenersOfDisconnect(CallHelper call) { for (Listener listener : mListeners) { listener.onDisconnect(call); } } /** * Updates the call entry in the local map. * @return false if no call previously existed and no call was added, otherwise true. */ private boolean updateCallInMap(CallHelper call) { Preconditions.checkNotNull(call); boolean updated = false; if (call.getState() == CallHelper.State.DISCONNECTED) { // update existing (but do not add!!) disconnected calls if (mCallById.containsKey(call.getId())) { // For disconnected calls, we want to keep them alive for a few seconds so that the // UI has a chance to display anything it needs when a call is disconnected. // Set up a timer to destroy the call after X seconds. final Message msg = mHandler.obtainMessage(EVENT_DISCONNECTED_TIMEOUT, call); mHandler.sendMessageDelayed(msg, getDelayForDisconnect(call)); mPendingDisconnectCalls.add(call); mCallById.put(call.getId(), call); mCallByTelecommCall.put(call.getTelecommCall(), call); updated = true; } } else if (!isCallDead(call)) { mCallById.put(call.getId(), call); mCallByTelecommCall.put(call.getTelecommCall(), call); updated = true; } else if (mCallById.containsKey(call.getId())) { mCallById.remove(call.getId()); mCallByTelecommCall.remove(call.getTelecommCall()); updated = true; } return updated; } private int getDelayForDisconnect(CallHelper call) { Preconditions.checkState(call.getState() == CallHelper.State.DISCONNECTED); final int cause = call.getDisconnectCause().getCode(); final int delay; switch (cause) { case DisconnectCause.LOCAL: delay = DISCONNECTED_CALL_SHORT_TIMEOUT_MS; break; case DisconnectCause.REMOTE: case DisconnectCause.ERROR: delay = DISCONNECTED_CALL_MEDIUM_TIMEOUT_MS; break; case DisconnectCause.REJECTED: case DisconnectCause.MISSED: case DisconnectCause.CANCELED: // no delay for missed/rejected incoming calls and canceled outgoing calls. delay = 0; break; default: delay = DISCONNECTED_CALL_LONG_TIMEOUT_MS; break; } return delay; } private void updateCallTextMap(CallHelper call, List<String> textResponses) { Preconditions.checkNotNull(call); if (!isCallDead(call)) { if (textResponses != null) { mCallTextReponsesMap.put(call.getId(), textResponses); } } else if (mCallById.containsKey(call.getId())) { mCallTextReponsesMap.remove(call.getId()); } } private boolean isCallDead(CallHelper call) { final int state = call.getState(); return CallHelper.State.IDLE == state || CallHelper.State.INVALID == state; } /** * Sets up a call for deletion and notifies listeners of change. */ private void finishDisconnectedCall(CallHelper call) { if (mPendingDisconnectCalls.contains(call)) { mPendingDisconnectCalls.remove(call); } call.setState(CallHelper.State.IDLE); updateCallInMap(call); notifyGenericListeners(); } /** * Notifies all video calls of a change in device orientation. * * @param rotation The new rotation angle (in degrees). */ public void notifyCallsOfDeviceRotation(int rotation) { for (CallHelper call : mCallById.values()) { // First, ensure a VideoCall is set on the call so that the change can be sent to the // provider (a VideoCall can be present for a call that does not currently have video, // but can be upgraded to video). // Second, ensure that the call videoState has video enabled (there is no need to set // device orientation on a voice call which has not yet been upgraded to video). if (call.getVideoCall() != null && CallUtils.isVideoCall(call)) { call.getVideoCall().setDeviceOrientation(rotation); } } } /** * Handles the timeout for destroying disconnected calls. */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case EVENT_DISCONNECTED_TIMEOUT: // Log.d(this, "EVENT_DISCONNECTED_TIMEOUT ", msg.obj); finishDisconnectedCall((CallHelper) msg.obj); break; default: // Log.wtf(this, "Message not expected: " + msg.what); break; } } }; /** * Listener interface for any class that wants to be notified of changes * to the call list. */ public interface Listener { /** * Called when a new incoming call comes in. * This is the only method that gets called for incoming calls. Listeners * that want to perform an action on incoming call should respond in this method * because {@link #onCallListChange} does not automatically get called for * incoming calls. */ public void onIncomingCall(CallHelper call); /** * Called when a new modify call request comes in * This is the only method that gets called for modify requests. */ public void onUpgradeToVideo(CallHelper call); /** * Called anytime there are changes to the call list. The change can be switching call * states, updating information, etc. This method will NOT be called for new incoming * calls and for calls that switch to disconnected state. Listeners must add actions * to those method implementations if they want to deal with those actions. */ public void onCallListChange(CallList callList); /** * Called when a call switches to the disconnected state. This is the only method * that will get called upon disconnection. */ public void onDisconnect(CallHelper call); } public interface CallUpdateListener { // TODO: refactor and limit arg to be call state. Caller info is not needed. public void onCallChanged(CallHelper call); /** * Notifies of a change to the session modification state for a call. * * @param sessionModificationState The new session modification state. */ public void onSessionModificationStateChange(int sessionModificationState); /** * Notifies of a change to the last forwarded number for a call. */ public void onLastForwardedNumberChange(); /** * Notifies of a change to the child number for a call. */ public void onChildNumberChange(); } } 文件上也有@Override public void onCallAdded(Call call) { super.onCallAdded(call); Log.d("MyConnectionService","onCallAdded"); CallList.getInstance().onCallAdded(call); } @Override public void onCallRemoved(Call call) { super.onCallRemoved(call); Log.d("MyConnectionService","onCallRemoved"); CallList.getInstance().onCallRemoved(call); } (无论是否由管理员运行)。这对我有帮助。

答案 10 :(得分:0)

我的问题发生在一个特定的分支上。
显然分支的参考文件已损坏。我就是这样修的。

<块引用>

git checkout main
// 我删除了文件 .git\refs\heads\branch_xpto
git pull
git checkout branch_xpto